mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-03-03 02:21:33 +00:00
Merge remote-tracking branch 'origin/master' into HEAD
This commit is contained in:
3
Gemfile
3
Gemfile
@@ -9,7 +9,7 @@ gem 'i18n', '~> 0.6.11'
|
||||
gem 'nokogiri', '>= 1.6.7.1'
|
||||
|
||||
gem 'pg'
|
||||
gem 'spree', github: 'openfoodfoundation/spree', branch: '1-3-stable'
|
||||
gem 'spree', github: 'openfoodfoundation/spree', branch: 'spree-upgrade-step1c'
|
||||
gem 'spree_i18n', github: 'spree/spree_i18n', branch: '1-3-stable'
|
||||
gem 'spree_auth_devise', github: 'spree/spree_auth_devise', branch: '1-3-stable'
|
||||
|
||||
@@ -87,6 +87,7 @@ gem "foundation-rails"
|
||||
gem 'foundation_rails_helper', github: 'willrjmarshall/foundation_rails_helper', branch: "rails3"
|
||||
|
||||
gem 'jquery-rails'
|
||||
gem 'jquery-migrate-rails'
|
||||
gem 'css_splitter'
|
||||
|
||||
|
||||
|
||||
96
Gemfile.lock
96
Gemfile.lock
@@ -23,45 +23,48 @@ GIT
|
||||
|
||||
GIT
|
||||
remote: git://github.com/openfoodfoundation/spree.git
|
||||
revision: 6e3edfe40a5de8eba0095b2c5f3db9ea54c3afda
|
||||
branch: 1-3-stable
|
||||
revision: a4c439570b77afa50f9e36299811f293232bd281
|
||||
branch: spree-upgrade-step1c
|
||||
specs:
|
||||
spree (1.3.6.beta)
|
||||
spree_api (= 1.3.6.beta)
|
||||
spree_cmd (= 1.3.6.beta)
|
||||
spree_core (= 1.3.6.beta)
|
||||
spree_promo (= 1.3.6.beta)
|
||||
spree_sample (= 1.3.6.beta)
|
||||
spree_api (1.3.6.beta)
|
||||
spree_core (= 1.3.6.beta)
|
||||
spree (1.3.99)
|
||||
spree_api (= 1.3.99)
|
||||
spree_cmd (= 1.3.99)
|
||||
spree_core (= 1.3.99)
|
||||
spree_dash (= 1.3.99)
|
||||
spree_promo (= 1.3.99)
|
||||
spree_sample (= 1.3.99)
|
||||
spree_api (1.3.99)
|
||||
spree_core (= 1.3.99)
|
||||
versioncake (= 0.4.0)
|
||||
spree_cmd (1.3.6.beta)
|
||||
spree_cmd (1.3.99)
|
||||
thor (>= 0.14.6)
|
||||
spree_core (1.3.6.beta)
|
||||
activemerchant (~> 1.34)
|
||||
spree_core (1.3.99)
|
||||
activemerchant (~> 1.50.0)
|
||||
acts_as_list (= 0.1.4)
|
||||
awesome_nested_set (= 2.1.5)
|
||||
aws-sdk (~> 1.11.1)
|
||||
cancan (= 1.6.8)
|
||||
deface (>= 0.9.0)
|
||||
ffaker (~> 1.15.0)
|
||||
highline (= 1.6.18)
|
||||
jquery-rails (~> 2.2.0)
|
||||
highline (= 1.6.11)
|
||||
jquery-rails (~> 2.0)
|
||||
json (>= 1.5.5)
|
||||
kaminari (= 0.14.1)
|
||||
money (= 5.1.1)
|
||||
kaminari (= 0.13.0)
|
||||
money (= 5.0.0)
|
||||
paperclip (~> 3.0)
|
||||
rabl (= 0.7.2)
|
||||
rails (~> 3.2.16)
|
||||
rails (~> 3.2.13)
|
||||
ransack (= 0.7.2)
|
||||
select2-rails (= 3.5.9.3)
|
||||
state_machine (= 1.1.2)
|
||||
select2-rails (~> 3.2)
|
||||
state_machine (= 1.2.0)
|
||||
stringex (~> 1.3.2)
|
||||
truncate_html (~> 0.5.5)
|
||||
spree_promo (1.3.6.beta)
|
||||
spree_core (= 1.3.6.beta)
|
||||
spree_sample (1.3.6.beta)
|
||||
spree_core (= 1.3.6.beta)
|
||||
spree_dash (1.3.99)
|
||||
httparty (~> 0.8.1)
|
||||
spree_core (= 1.3.99)
|
||||
spree_promo (1.3.99)
|
||||
spree_core (= 1.3.99)
|
||||
spree_sample (1.3.99)
|
||||
spree_core (= 1.3.99)
|
||||
|
||||
GIT
|
||||
remote: git://github.com/spree/deface.git
|
||||
@@ -123,8 +126,8 @@ GEM
|
||||
sprockets (~> 2.2.1)
|
||||
active_model_serializers (0.8.3)
|
||||
activemodel (>= 3.0)
|
||||
activemerchant (1.57.0)
|
||||
activesupport (>= 3.2.14, < 5.1)
|
||||
activemerchant (1.50.0)
|
||||
activesupport (>= 3.2.14, < 5.0.0)
|
||||
builder (>= 2.1.2, < 4.0.0)
|
||||
i18n (>= 0.6.9)
|
||||
nokogiri (~> 1.4)
|
||||
@@ -167,9 +170,7 @@ GEM
|
||||
bcrypt-ruby (3.1.5)
|
||||
bcrypt (>= 3.1.3)
|
||||
blockenspiel (0.4.5)
|
||||
bugsnag (1.5.2)
|
||||
httparty (>= 0.6, < 1.0)
|
||||
multi_json (~> 1.0)
|
||||
bugsnag (4.1.0)
|
||||
builder (3.0.4)
|
||||
byebug (2.7.0)
|
||||
columnize (~> 0.3)
|
||||
@@ -189,7 +190,7 @@ GEM
|
||||
climate_control (0.0.3)
|
||||
activesupport (>= 3.0)
|
||||
cliver (0.3.2)
|
||||
cocaine (0.5.7)
|
||||
cocaine (0.5.8)
|
||||
climate_control (>= 0.0.3, < 1.0)
|
||||
coderay (1.0.9)
|
||||
coffee-rails (3.2.2)
|
||||
@@ -404,12 +405,12 @@ GEM
|
||||
zeus
|
||||
haml (4.0.4)
|
||||
tilt
|
||||
highline (1.6.18)
|
||||
highline (1.6.11)
|
||||
hike (1.2.3)
|
||||
http_parser.rb (0.5.3)
|
||||
httparty (0.13.1)
|
||||
json (~> 1.8)
|
||||
multi_xml (>= 0.5.2)
|
||||
httparty (0.8.3)
|
||||
multi_json (~> 1.0)
|
||||
multi_xml
|
||||
i18n (0.6.11)
|
||||
immigrant (0.1.6)
|
||||
activerecord (>= 3.0)
|
||||
@@ -417,16 +418,18 @@ GEM
|
||||
inflecto (0.0.2)
|
||||
ipaddress (0.8.0)
|
||||
journey (1.0.4)
|
||||
jquery-rails (2.2.2)
|
||||
jquery-migrate-rails (1.2.1)
|
||||
jquery-rails (2.3.0)
|
||||
railties (>= 3.0, < 5.0)
|
||||
thor (>= 0.14, < 2.0)
|
||||
json (1.8.3)
|
||||
json_spec (1.1.1)
|
||||
multi_json (~> 1.0)
|
||||
rspec (~> 2.0)
|
||||
kaminari (0.14.1)
|
||||
kaminari (0.13.0)
|
||||
actionpack (>= 3.0.0)
|
||||
activesupport (>= 3.0.0)
|
||||
railties (>= 3.0.0)
|
||||
kgio (2.9.3)
|
||||
knapsack (1.5.1)
|
||||
rake
|
||||
@@ -449,8 +452,9 @@ GEM
|
||||
mini_portile2 (2.0.0)
|
||||
momentjs-rails (2.5.1)
|
||||
railties (>= 3.1)
|
||||
money (5.1.1)
|
||||
i18n (~> 0.6.0)
|
||||
money (5.0.0)
|
||||
i18n (~> 0.4)
|
||||
json
|
||||
multi_json (1.12.1)
|
||||
multi_xml (0.5.5)
|
||||
newrelic_rpm (3.12.0.288)
|
||||
@@ -494,7 +498,7 @@ GEM
|
||||
activesupport (>= 2.3.14)
|
||||
multi_json (~> 1.0)
|
||||
rack (1.4.7)
|
||||
rack-cache (1.2)
|
||||
rack-cache (1.6.1)
|
||||
rack (>= 0.4)
|
||||
rack-livereload (0.3.15)
|
||||
rack
|
||||
@@ -521,7 +525,7 @@ GEM
|
||||
rdoc (~> 3.4)
|
||||
thor (>= 0.14.6, < 2.0)
|
||||
raindrops (0.13.0)
|
||||
rake (10.4.2)
|
||||
rake (11.1.2)
|
||||
ransack (0.7.2)
|
||||
actionpack (~> 3.0)
|
||||
activerecord (~> 3.0)
|
||||
@@ -571,7 +575,7 @@ GEM
|
||||
railties (~> 3.2.0)
|
||||
sass (>= 3.1.10)
|
||||
tilt (~> 1.3)
|
||||
select2-rails (3.5.9.3)
|
||||
select2-rails (3.5.10)
|
||||
thor (~> 0.14)
|
||||
shoulda-matchers (1.1.0)
|
||||
activesupport (>= 3.0.0)
|
||||
@@ -583,7 +587,7 @@ GEM
|
||||
multi_json (~> 1.0)
|
||||
rack (~> 1.0)
|
||||
tilt (~> 1.1, != 1.3.0)
|
||||
state_machine (1.1.2)
|
||||
state_machine (1.2.0)
|
||||
stringex (1.3.3)
|
||||
therubyracer (0.12.0)
|
||||
libv8 (~> 3.16.14.0)
|
||||
@@ -601,7 +605,7 @@ GEM
|
||||
sprockets (>= 2.0.0)
|
||||
turn (0.8.3)
|
||||
ansi
|
||||
tzinfo (0.3.44)
|
||||
tzinfo (0.3.49)
|
||||
uglifier (2.7.1)
|
||||
execjs (>= 0.3.0)
|
||||
json (>= 1.8.0)
|
||||
@@ -682,6 +686,7 @@ DEPENDENCIES
|
||||
haml
|
||||
i18n (~> 0.6.11)
|
||||
immigrant
|
||||
jquery-migrate-rails
|
||||
jquery-rails
|
||||
json_spec
|
||||
knapsack
|
||||
@@ -728,5 +733,8 @@ DEPENDENCIES
|
||||
wicked_pdf
|
||||
wkhtmltopdf-binary
|
||||
|
||||
RUBY VERSION
|
||||
ruby 2.1.5p273
|
||||
|
||||
BUNDLED WITH
|
||||
1.12.5
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
//
|
||||
|
||||
//= require jquery
|
||||
//= require jquery-migrate-min
|
||||
//= require jquery_ujs
|
||||
//= require jquery-ui
|
||||
//= require shared/jquery-ui-timepicker-addon
|
||||
|
||||
@@ -27,7 +27,7 @@ angular.module("admin.enterprises")
|
||||
|
||||
# Provide a callback for generating warning messages displayed before leaving the page. This is passed in
|
||||
# from a directive "nav-check" in the page - if we pass it here it will be called in the test suite,
|
||||
# and on all new uses of this contoller, and we might not want that .
|
||||
# and on all new uses of this contoller, and we might not want that.
|
||||
enterpriseNavCallback = ->
|
||||
if $scope.Enterprise.$dirty
|
||||
"Your changes to the enterprise are not saved yet."
|
||||
|
||||
@@ -4,16 +4,11 @@ angular.module("admin.enterprises").factory 'Enterprises', ($q, EnterpriseResour
|
||||
pristineByID: {}
|
||||
|
||||
index: (params={}, callback=null) ->
|
||||
includeBlank = !!params['includeBlank']
|
||||
delete params['includeBlank']
|
||||
EnterpriseResource.index(params, (data) =>
|
||||
for enterprise in data
|
||||
@enterprisesByID[enterprise.id] = enterprise
|
||||
@pristineByID[enterprise.id] = angular.copy(enterprise)
|
||||
|
||||
(callback || angular.noop)(data)
|
||||
|
||||
data.unshift(blankOption()) if includeBlank
|
||||
data
|
||||
)
|
||||
|
||||
|
||||
@@ -3,19 +3,42 @@ angular.module("admin.indexUtils").directive "ofnSelect2", ($sanitize, $timeout,
|
||||
restrict: 'C'
|
||||
scope:
|
||||
data: "="
|
||||
minSearch: "@?"
|
||||
text: "@?"
|
||||
minSearch: "@"
|
||||
text: "@"
|
||||
blank: "=?"
|
||||
filter: "=?"
|
||||
onSelecting: "=?"
|
||||
multiple: '@'
|
||||
link: (scope, element, attrs, ngModel) ->
|
||||
$timeout ->
|
||||
scope.text ||= 'name'
|
||||
scope.filter ||= -> true
|
||||
scope.text ?= 'name'
|
||||
scope.multiple ?= false
|
||||
scope.filter ?= -> true
|
||||
|
||||
if scope.data.$promise
|
||||
scope.data.$promise.then -> init()
|
||||
else
|
||||
init()
|
||||
|
||||
element.on "select2-opening", scope.onSelecting || angular.noop
|
||||
|
||||
attrs.$observe 'disabled', (value) ->
|
||||
element.select2('enable', !value)
|
||||
|
||||
ngModel.$formatters.push (value) ->
|
||||
element.select2('val', value)
|
||||
value
|
||||
|
||||
ngModel.$parsers.push (value) ->
|
||||
return value.split(",") if scope.multiple
|
||||
value
|
||||
|
||||
init = ->
|
||||
scope.data.unshift(scope.blank) if scope.blank? && typeof scope.blank is "object"
|
||||
|
||||
item.name = $sanitize(item.name) for item in scope.data
|
||||
element.select2
|
||||
multiple: scope.multiple
|
||||
minimumResultsForSearch: scope.minSearch || 0
|
||||
data: ->
|
||||
filtered = $filter('filter')(scope.data,scope.filter)
|
||||
@@ -24,12 +47,3 @@ angular.module("admin.indexUtils").directive "ofnSelect2", ($sanitize, $timeout,
|
||||
item[scope.text]
|
||||
formatResult: (item) ->
|
||||
item[scope.text]
|
||||
|
||||
element.on "select2-opening", scope.onSelecting || angular.noop
|
||||
|
||||
attrs.$observe 'disabled', (value) ->
|
||||
element.select2('enable', !value)
|
||||
|
||||
ngModel.$formatters.push (value) ->
|
||||
element.select2('val', value)
|
||||
value
|
||||
|
||||
@@ -3,7 +3,8 @@ angular.module("admin.indexUtils").factory 'Dereferencer', ->
|
||||
dereference: (array, data)->
|
||||
if array
|
||||
for object, i in array
|
||||
array[i] = data[object.id]
|
||||
match = data[object.id]
|
||||
array[i] = match if match?
|
||||
|
||||
dereferenceAttr: (array, attr, data)->
|
||||
if array
|
||||
|
||||
@@ -15,13 +15,13 @@ angular.module("admin.lineItems").controller 'LineItemsCtrl', ($scope, $timeout,
|
||||
LineItems.allSaved() || confirm(t("unsaved_changes_warning"))
|
||||
|
||||
$scope.resetSelectFilters = ->
|
||||
$scope.distributorFilter = blankOption().id
|
||||
$scope.supplierFilter = blankOption().id
|
||||
$scope.orderCycleFilter = blankOption().id
|
||||
$scope.distributorFilter = 0
|
||||
$scope.supplierFilter = 0
|
||||
$scope.orderCycleFilter = 0
|
||||
$scope.quickSearch = ""
|
||||
|
||||
$scope.refreshData = ->
|
||||
unless !$scope.orderCycleFilter? || $scope.orderCycleFilter == "0"
|
||||
unless !$scope.orderCycleFilter? || $scope.orderCycleFilter == 0
|
||||
$scope.startDate = OrderCycles.orderCyclesByID[$scope.orderCycleFilter].first_order
|
||||
$scope.endDate = OrderCycles.orderCyclesByID[$scope.orderCycleFilter].last_order
|
||||
|
||||
@@ -29,9 +29,9 @@ angular.module("admin.lineItems").controller 'LineItemsCtrl', ($scope, $timeout,
|
||||
RequestMonitor.load $scope.lineItems = LineItems.index("q[order][state_not_eq]": "canceled", "q[order][completed_at_not_null]": "true", "q[order][completed_at_gt]": "#{parseDate($scope.startDate)}", "q[order][completed_at_lt]": "#{parseDate($scope.endDate)}")
|
||||
|
||||
unless $scope.initialized
|
||||
RequestMonitor.load $scope.distributors = Enterprises.index(includeBlank: true, action: "for_line_items", ams_prefix: "basic", "q[sells_in][]": ["own", "any"])
|
||||
RequestMonitor.load $scope.orderCycles = OrderCycles.index(includeBlank: true, ams_prefix: "basic", as: "distributor", "q[orders_close_at_gt]": "#{daysFromToday(-90)}")
|
||||
RequestMonitor.load $scope.suppliers = Enterprises.index(includeBlank: true, action: "for_line_items", ams_prefix: "basic", "q[is_primary_producer_eq]": "true")
|
||||
RequestMonitor.load $scope.distributors = Enterprises.index(action: "for_line_items", ams_prefix: "basic", "q[sells_in][]": ["own", "any"])
|
||||
RequestMonitor.load $scope.orderCycles = OrderCycles.index(ams_prefix: "basic", as: "distributor", "q[orders_close_at_gt]": "#{daysFromToday(-90)}")
|
||||
RequestMonitor.load $scope.suppliers = Enterprises.index(action: "for_line_items", ams_prefix: "basic", "q[is_primary_producer_eq]": "true")
|
||||
|
||||
RequestMonitor.load $q.all([$scope.orders.$promise, $scope.distributors.$promise, $scope.orderCycles.$promise]).then ->
|
||||
Dereferencer.dereferenceAttr $scope.orders, "distributor", Enterprises.enterprisesByID
|
||||
|
||||
@@ -2,7 +2,7 @@ angular.module("admin.lineItems").filter "selectFilter", (blankOption, RequestMo
|
||||
return (lineItems,selectedSupplier,selectedDistributor,selectedOrderCycle) ->
|
||||
filtered = []
|
||||
unless RequestMonitor.loading
|
||||
filtered.push lineItem for lineItem in lineItems when (angular.equals(selectedSupplier,"0") || lineItem.supplier.id == selectedSupplier) &&
|
||||
(angular.equals(selectedDistributor,"0") || lineItem.order.distributor.id == selectedDistributor) &&
|
||||
(angular.equals(selectedOrderCycle,"0") || lineItem.order.order_cycle.id == selectedOrderCycle)
|
||||
filtered.push lineItem for lineItem in lineItems when (angular.equals(selectedSupplier,0) || lineItem.supplier.id == selectedSupplier) &&
|
||||
(angular.equals(selectedDistributor,0) || lineItem.order.distributor.id == selectedDistributor) &&
|
||||
(angular.equals(selectedOrderCycle,0) || lineItem.order.order_cycle.id == selectedOrderCycle)
|
||||
filtered
|
||||
|
||||
@@ -30,8 +30,16 @@ show_flash_error = function(message) {
|
||||
}
|
||||
|
||||
$(document).ready(function(){
|
||||
$('a.close').click(function(event){
|
||||
event.preventDefault();
|
||||
$(this).parent().slideUp(250);
|
||||
});
|
||||
$('a.close').click(function(event){
|
||||
event.preventDefault();
|
||||
$(this).parent().slideUp(250);
|
||||
});
|
||||
|
||||
// Spree locates hidden with prev(), which with our current version of jQuery
|
||||
// does not locate the hidden field, resulting in the delete failing. This
|
||||
// handler updates the hidden field, fixing the problem.
|
||||
$('body').on('click', 'a.remove_fields', function() {
|
||||
$(this).next("input[type=hidden]").val("1");
|
||||
return false;
|
||||
});
|
||||
});
|
||||
|
||||
@@ -2,6 +2,10 @@ require 'open_food_network/referer_parser'
|
||||
|
||||
module Admin
|
||||
class EnterprisesController < ResourceController
|
||||
# These need to run before #load_resource so that @object is initialised with sanitised values
|
||||
prepend_before_filter :override_owner, only: :create
|
||||
prepend_before_filter :override_sells, only: :create
|
||||
|
||||
before_filter :load_enterprise_set, :only => :index
|
||||
before_filter :load_countries, :except => [:index, :register, :check_permalink]
|
||||
before_filter :load_methods_and_fees, :only => [:edit, :update]
|
||||
@@ -9,8 +13,6 @@ module Admin
|
||||
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 :override_sells, 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
|
||||
@@ -115,8 +117,8 @@ module Admin
|
||||
|
||||
def build_resource_with_address
|
||||
enterprise = build_resource_without_address
|
||||
enterprise.address = Spree::Address.new
|
||||
enterprise.address.country = Spree::Country.find_by_id(Spree::Config[:default_country_id])
|
||||
enterprise.address ||= Spree::Address.new
|
||||
enterprise.address.country ||= Spree::Country.find_by_id(Spree::Config[:default_country_id])
|
||||
enterprise
|
||||
end
|
||||
alias_method_chain :build_resource, :address
|
||||
@@ -269,9 +271,10 @@ module Admin
|
||||
# Overriding method on Spree's resource controller
|
||||
def location_after_save
|
||||
referer_path = OpenFoodNetwork::RefererParser::path(request.referer)
|
||||
refered_from_edit = referer_path =~ /\/edit$/
|
||||
if params[:enterprise].key?(:producer_properties_attributes) && !refered_from_edit
|
||||
main_app.admin_enterprises_path
|
||||
refered_from_producer_properties = referer_path =~ /\/producer_properties$/
|
||||
|
||||
if refered_from_producer_properties
|
||||
main_app.admin_enterprise_producer_properties_path(@enterprise)
|
||||
else
|
||||
main_app.edit_admin_enterprise_path(@enterprise)
|
||||
end
|
||||
|
||||
@@ -20,6 +20,11 @@ class ApplicationController < ActionController::Base
|
||||
|
||||
private
|
||||
|
||||
def action
|
||||
params[:action].to_sym
|
||||
end
|
||||
|
||||
|
||||
def require_distributor_chosen
|
||||
unless @distributor = current_distributor
|
||||
redirect_to spree.root_path
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
require 'spree/core/controller_helpers/respond_with_decorator'
|
||||
require 'open_food_network/tag_rule_applicator'
|
||||
|
||||
class BaseController < ApplicationController
|
||||
include Spree::Core::ControllerHelpers
|
||||
include Spree::Core::ControllerHelpers::Auth
|
||||
include Spree::Core::ControllerHelpers::Common
|
||||
include Spree::Core::ControllerHelpers::Order
|
||||
include Spree::Core::ControllerHelpers::RespondWith
|
||||
|
||||
include EnterprisesHelper
|
||||
include OrderCyclesHelper
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
module Spree
|
||||
module Admin
|
||||
AdjustmentsController.class_eval do
|
||||
before_filter :set_included_tax, only: [:create, :update]
|
||||
prepend_before_filter :set_included_tax, only: [:create, :update]
|
||||
before_filter :set_default_tax_rate, only: :edit
|
||||
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
require 'spree/core/controller_helpers/respond_with_decorator'
|
||||
|
||||
Spree::Admin::BaseController.class_eval do
|
||||
before_filter :warn_invalid_order_cycles
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@ Spree::Admin::ProductsController.class_eval do
|
||||
before_filter :load_spree_api_key, :only => [:bulk_edit, :variant_overrides]
|
||||
before_filter :strip_new_properties, only: [:create, :update]
|
||||
|
||||
alias_method :location_after_save_original, :location_after_save
|
||||
|
||||
respond_to :json, :only => :clone
|
||||
|
||||
@@ -53,14 +52,17 @@ Spree::Admin::ProductsController.class_eval do
|
||||
|
||||
|
||||
protected
|
||||
def location_after_save
|
||||
|
||||
def location_after_save_with_bulk_edit
|
||||
referer_path = OpenFoodNetwork::RefererParser::path(request.referer)
|
||||
|
||||
if referer_path == '/admin/products/bulk_edit'
|
||||
bulk_edit_admin_products_url
|
||||
else
|
||||
location_after_save_original
|
||||
location_after_save_without_bulk_edit
|
||||
end
|
||||
end
|
||||
alias_method_chain :location_after_save, :bulk_edit
|
||||
|
||||
def collection
|
||||
# This method is copied directly from the spree product controller, except where we narrow the search below with the managed_by search to support
|
||||
|
||||
16
app/controllers/spree/admin/resource_controller_decorator.rb
Normal file
16
app/controllers/spree/admin/resource_controller_decorator.rb
Normal file
@@ -0,0 +1,16 @@
|
||||
module AuthorizeOnLoadResource
|
||||
def load_resource
|
||||
super
|
||||
|
||||
if member_action?
|
||||
# If we don't have access, clear the object
|
||||
unless can? action, @object
|
||||
instance_variable_set("@#{object_name}", nil)
|
||||
end
|
||||
|
||||
authorize! action, @object
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Spree::Admin::ResourceController.send(:prepend, AuthorizeOnLoadResource)
|
||||
7
app/controllers/spree/api/users_controller.rb
Normal file
7
app/controllers/spree/api/users_controller.rb
Normal file
@@ -0,0 +1,7 @@
|
||||
module Spree
|
||||
module Api
|
||||
class UsersController < Spree::Api::BaseController
|
||||
respond_to :json
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -40,7 +40,6 @@ Spree::OrdersController.class_eval do
|
||||
|
||||
if @order.update_attributes(params[:order])
|
||||
@order.line_items = @order.line_items.select {|li| li.quantity > 0 }
|
||||
@order.restart_checkout_flow
|
||||
|
||||
render :edit and return unless apply_coupon_code
|
||||
|
||||
|
||||
@@ -1,22 +1,6 @@
|
||||
module Spree
|
||||
module Admin
|
||||
module BaseHelper
|
||||
# Add url option to pass in link URL
|
||||
def link_to_remove_fields(name, f, options = {})
|
||||
name = '' if options[:no_text]
|
||||
options[:class] = '' unless options[:class]
|
||||
options[:class] += 'no-text' if options[:no_text]
|
||||
|
||||
url = if f.object.persisted?
|
||||
options[:url] || [:admin, f.object]
|
||||
else
|
||||
'#'
|
||||
end
|
||||
|
||||
link_to_with_icon('icon-trash', name, url, :class => "remove_fields #{options[:class]}", :data => {:action => 'remove'}, :title => t(:remove)) + f.hidden_field(:_destroy)
|
||||
end
|
||||
|
||||
|
||||
def preference_field_tag_with_files(name, value, options)
|
||||
if options[:type] == :file
|
||||
file_field_tag name, preference_field_options(options)
|
||||
@@ -25,6 +9,20 @@ module Spree
|
||||
end
|
||||
end
|
||||
alias_method_chain :preference_field_tag, :files
|
||||
|
||||
|
||||
# Add support for options[:html], allowing additional HTML attributes
|
||||
def link_to_remove_fields(name, f, options = {})
|
||||
name = '' if options[:no_text]
|
||||
options[:class] = '' unless options[:class]
|
||||
options[:class] += 'no-text with-tip' if options[:no_text]
|
||||
|
||||
html_options = {class: "remove_fields #{options[:class]}", data: {action: 'remove'}, title: t(:remove)}
|
||||
html_options.merge!(options[:html]) if options.key? :html
|
||||
|
||||
link_to_with_icon('icon-trash', name, '#', html_options) + f.hidden_field(:_destroy)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -4,14 +4,14 @@ module Spree
|
||||
# Make it so that the Reports admin tab can be enabled/disabled through the cancan
|
||||
# :report resource, since it does not have a corresponding resource class (unlike
|
||||
# eg. Spree::Product).
|
||||
def klass_for_with_sym_fallback(name)
|
||||
klass = klass_for_without_sym_fallback(name)
|
||||
klass ||= name.singularize.to_sym
|
||||
klass = :overview if klass == :dashboard
|
||||
klass = Spree::Order if klass == :bulk_order_management
|
||||
klass
|
||||
end
|
||||
alias_method_chain :klass_for, :sym_fallback
|
||||
# def klass_for_with_sym_fallback(name)
|
||||
# klass = klass_for_without_sym_fallback(name)
|
||||
# klass ||= name.singularize.to_sym
|
||||
# klass = :overview if klass == :dashboard
|
||||
# klass = Spree::Order if klass == :bulk_order_management
|
||||
# klass
|
||||
# end
|
||||
# alias_method_chain :klass_for, :sym_fallback
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -6,6 +6,13 @@ Spree::BaseMailer.class_eval do
|
||||
layout 'mailer'
|
||||
|
||||
protected
|
||||
|
||||
def from_address
|
||||
Spree::MailMethod.current.andand.preferred_mails_from ||
|
||||
'test@example.com'
|
||||
end
|
||||
|
||||
|
||||
def roadie_options
|
||||
# This lets us specify assets using relative paths in email templates
|
||||
super.merge(url_options: {host: URI(spree.root_url).host })
|
||||
|
||||
@@ -3,6 +3,13 @@ Spree::OrderMailer.class_eval do
|
||||
helper CheckoutHelper
|
||||
helper SpreeCurrencyHelper
|
||||
|
||||
def cancel_email(order, resend = false)
|
||||
@order = find_order(order)
|
||||
subject = (resend ? "[#{t(:resend).upcase}] " : '')
|
||||
subject += "#{Spree::Config[:site_name]} #{t('order_mailer.cancel_email.subject')} ##{order.number}"
|
||||
mail(to: order.email, from: from_address, subject: subject)
|
||||
end
|
||||
|
||||
def confirm_email_for_customer(order, resend = false)
|
||||
find_order(order) # Finds an order instance from an id
|
||||
subject = (resend ? "[#{t(:resend).upcase}] " : '')
|
||||
@@ -31,4 +38,8 @@ Spree::OrderMailer.class_eval do
|
||||
:subject => subject,
|
||||
:reply_to => @order.distributor.email)
|
||||
end
|
||||
|
||||
def find_order(order)
|
||||
@order = order.respond_to?(:id) ? order : Spree::Order.find(order)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -78,6 +78,7 @@ class Enterprise < ActiveRecord::Base
|
||||
validate :enforce_ownership_limit, if: lambda { owner_id_changed? && !owner_id.nil? }
|
||||
validates_length_of :description, :maximum => 255
|
||||
|
||||
|
||||
before_save :confirmation_check, if: lambda { email_changed? }
|
||||
|
||||
before_validation :initialize_permalink, if: lambda { permalink.nil? }
|
||||
@@ -93,6 +94,7 @@ class Enterprise < ActiveRecord::Base
|
||||
|
||||
after_rollback :restore_permalink
|
||||
|
||||
|
||||
scope :by_name, order('name')
|
||||
scope :visible, where(visible: true)
|
||||
scope :confirmed, where('confirmed_at IS NOT NULL')
|
||||
|
||||
@@ -16,6 +16,7 @@ class EnterpriseFee < ActiveRecord::Base
|
||||
|
||||
calculated_adjustments
|
||||
|
||||
|
||||
attr_accessible :enterprise_id, :fee_type, :name, :tax_category_id, :calculator_type, :inherits_tax_category
|
||||
|
||||
FEE_TYPES = %w(packing transport admin sales fundraising)
|
||||
|
||||
@@ -58,14 +58,14 @@ class EnterpriseGroup < ActiveRecord::Base
|
||||
}
|
||||
|
||||
def set_unused_address_fields
|
||||
address.firstname = address.lastname = 'unused' if address.present?
|
||||
address.firstname = address.lastname = 'unused'
|
||||
end
|
||||
|
||||
def set_undefined_address_fields
|
||||
return unless address.present?
|
||||
address.phone.present? || address.phone = 'undefined'
|
||||
address.address1.present? || address.address1 = 'undefined'
|
||||
address.city.present? || address.city = 'undefined'
|
||||
address.state.present? || address.state = address.country.states.first
|
||||
address.zipcode.present? || address.zipcode = 'undefined'
|
||||
end
|
||||
|
||||
|
||||
@@ -110,12 +110,12 @@ class AbilityDecorator
|
||||
def add_product_management_abilities(user)
|
||||
# Enterprise User can only access products that they are a supplier for
|
||||
can [:create], Spree::Product
|
||||
can [:admin, :read, :update, :product_distributions, :bulk_edit, :bulk_update, :clone, :destroy], Spree::Product do |product|
|
||||
can [:admin, :read, :update, :product_distributions, :bulk_edit, :bulk_update, :clone, :delete, :destroy], Spree::Product do |product|
|
||||
OpenFoodNetwork::Permissions.new(user).managed_product_enterprises.include? product.supplier
|
||||
end
|
||||
|
||||
can [:create], Spree::Variant
|
||||
can [:admin, :index, :read, :edit, :update, :search, :destroy], Spree::Variant do |variant|
|
||||
can [:admin, :index, :read, :edit, :update, :search, :delete, :destroy], Spree::Variant do |variant|
|
||||
OpenFoodNetwork::Permissions.new(user).managed_product_enterprises.include? variant.product.supplier
|
||||
end
|
||||
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
module Spree
|
||||
Calculator::FlatPercentItemTotal.class_eval do
|
||||
def compute(object)
|
||||
item_total = line_items_for(object).map(&:amount).sum
|
||||
value = item_total * BigDecimal(self.preferred_flat_percent.to_s) / 100.0
|
||||
(value * 100).round.to_f / 100
|
||||
end
|
||||
end
|
||||
end
|
||||
19
app/models/spree/calculator/flexi_rate_decorator.rb
Normal file
19
app/models/spree/calculator/flexi_rate_decorator.rb
Normal file
@@ -0,0 +1,19 @@
|
||||
module Spree
|
||||
Calculator::FlexiRate.class_eval do
|
||||
def compute(object)
|
||||
sum = 0
|
||||
max = self.preferred_max_items.to_i
|
||||
items_count = line_items_for(object).map(&:quantity).sum
|
||||
items_count.times do |i|
|
||||
# check max value to avoid divide by 0 errors
|
||||
if (max == 0 && i == 0) || (max > 0) && (i % max == 0)
|
||||
sum += self.preferred_first_item.to_f
|
||||
else
|
||||
sum += self.preferred_additional_item.to_f
|
||||
end
|
||||
end
|
||||
|
||||
sum
|
||||
end
|
||||
end
|
||||
end
|
||||
15
app/models/spree/calculator/per_item_decorator.rb
Normal file
15
app/models/spree/calculator/per_item_decorator.rb
Normal file
@@ -0,0 +1,15 @@
|
||||
module Spree
|
||||
Calculator::PerItem.class_eval do
|
||||
def compute(object=nil)
|
||||
return 0 if object.nil?
|
||||
self.preferred_amount * line_items_for(object).reduce(0) do |sum, value|
|
||||
if matching_products.blank? || matching_products.include?(value.product)
|
||||
value_to_add = value.quantity
|
||||
else
|
||||
value_to_add = 0
|
||||
end
|
||||
sum + value_to_add
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
18
app/models/spree/calculator_decorator.rb
Normal file
18
app/models/spree/calculator_decorator.rb
Normal file
@@ -0,0 +1,18 @@
|
||||
module Spree
|
||||
Calculator.class_eval do
|
||||
|
||||
|
||||
private
|
||||
|
||||
# Given an object which might be an Order or a LineItem (amongst
|
||||
# others), return a collection of line items.
|
||||
def line_items_for(object)
|
||||
if object.respond_to? :line_items
|
||||
object.line_items
|
||||
else
|
||||
[object]
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
@@ -35,7 +35,7 @@ Spree::Order.class_eval do
|
||||
order.payment_required?
|
||||
}
|
||||
go_to_state :confirm, :if => lambda { |order| order.confirmation_required? }
|
||||
go_to_state :complete, :if => lambda { |order| (order.payment_required? && order.has_unprocessed_payments?) || !order.payment_required? }
|
||||
go_to_state :complete
|
||||
remove_transition :from => :delivery, :to => :confirm
|
||||
end
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
Spree::PaymentMethod.class_eval do
|
||||
Spree::PaymentMethod::DISPLAY = [:both, :front_end, :back_end]
|
||||
|
||||
acts_as_taggable
|
||||
|
||||
has_and_belongs_to_many :distributors, join_table: 'distributors_payment_methods', :class_name => 'Enterprise', association_foreign_key: 'distributor_id'
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
class Api::CurrencyConfigSerializer < ActiveModel::Serializer
|
||||
attributes :currency, :display_currency, :symbol, :symbol_position, :hide_cents, :decimal_mark, :thousands_separator
|
||||
attributes :currency, :display_currency, :symbol, :symbol_position, :hide_cents
|
||||
|
||||
def currency
|
||||
Spree::Config[:currency]
|
||||
@@ -13,20 +13,12 @@ class Api::CurrencyConfigSerializer < ActiveModel::Serializer
|
||||
::Money.new(1, Spree::Config[:currency]).symbol
|
||||
end
|
||||
|
||||
def symbol_position
|
||||
def symbol_position
|
||||
Spree::Config[:currency_symbol_position]
|
||||
end
|
||||
|
||||
def hide_cents
|
||||
def hide_cents
|
||||
Spree::Config[:hide_cents]
|
||||
end
|
||||
|
||||
def decimal_mark
|
||||
Spree::Config[:currency_decimal_mark]
|
||||
end
|
||||
|
||||
def thousands_separator
|
||||
Spree::Config[:currency_thousands_separator]
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -12,4 +12,4 @@
|
||||
= f.text_field :value, :class => 'autocomplete'
|
||||
%td.actions
|
||||
- unless @enterprise.producer_properties.empty?
|
||||
= link_to_remove_fields t(:remove), f, no_text: true, url: (f.object.persisted? && main_app.admin_enterprise_producer_property_path(@enterprise, f.object))
|
||||
= link_to_remove_fields t(:remove), f, no_text: true, url: (f.object.persisted? && main_app.admin_enterprise_producer_property_path(@enterprise, f.object)), html: {"onclick" => "if(typeof(enterprise_form) != 'undefined') { angular.element(enterprise_form).scope().setFormDirty() }".html_safe}
|
||||
|
||||
@@ -31,17 +31,17 @@
|
||||
%label{ :for => 'supplier_filter' }
|
||||
= t("admin.producer")
|
||||
%br
|
||||
%select{ :class => "three columns alpha", :id => 'supplier_filter', 'select2-min-search' => 5, 'ng-model' => 'supplierFilter', 'ng-options' => 's.id as s.name for s in suppliers' }
|
||||
%input#supplier_filter.ofn-select2.fullwidth{ type: 'number', 'min-search' => 5, data: 'suppliers', blank: "{ id: 0, name: 'All' }", ng: { model: 'supplierFilter' } }
|
||||
.filter_select{ :class => "three columns" }
|
||||
%label{ :for => 'distributor_filter' }
|
||||
= t("admin.shop")
|
||||
%br
|
||||
%select{ :class => "three columns alpha", :id => 'distributor_filter', 'select2-min-search' => 5, 'ng-model' => 'distributorFilter', 'ng-options' => 'd.id as d.name for d in distributors'}
|
||||
%input#distributor_filter.ofn-select2.fullwidth{ type: 'number', 'min-search' => 5, data: 'distributors', blank: "{ id: 0, name: 'All' }", ng: { model: 'distributorFilter' } }
|
||||
.filter_select{ :class => "three columns" }
|
||||
%label{ :for => 'order_cycle_filter' }
|
||||
= t("admin.order_cycle")
|
||||
%br
|
||||
%select{ :class => "three columns alpha", :id => 'order_cycle_filter', 'select2-min-search' => 5, 'ng-model' => 'orderCycleFilter', 'ng-options' => 'oc.id as oc.name for oc in orderCycles', 'confirm-change' => "confirmRefresh()", 'ng-change' => 'refreshData()'}
|
||||
%input#order_cycle_filter.ofn-select2.fullwidth{ type: 'number', 'min-search' => 5, data: 'orderCycles', blank: "{ id: 0, name: 'All' }", on: { selecting: "confirmRefresh" }, ng: { model: 'orderCycleFilter', change: 'refreshData()' } }
|
||||
.filter_clear{ :class => "two columns omega" }
|
||||
%label{ :for => 'clear_all_filters' }
|
||||
%br
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
|
||||
require 'spree/product_filters'
|
||||
require 'spree/core/calculated_adjustments_decorator'
|
||||
|
||||
require "#{Rails.root}/app/models/spree/payment_method_decorator"
|
||||
require "#{Rails.root}/app/models/spree/gateway_decorator"
|
||||
|
||||
@@ -1074,6 +1074,9 @@ Please follow the instructions there to make your enterprise visible on the Open
|
||||
validation_msg_is_associated_with_an_exising_customer: "is associated with an existing customer"
|
||||
|
||||
spree:
|
||||
date_picker:
|
||||
format: ! '%Y-%m-%d'
|
||||
js_format: 'yy-mm-dd'
|
||||
zipcode: Postcode
|
||||
shipment_states:
|
||||
backorder: backorder
|
||||
|
||||
@@ -5,13 +5,11 @@ module OpenFoodNetwork
|
||||
end
|
||||
|
||||
def self.parse_uri(string)
|
||||
begin
|
||||
# TODO: make this operation obsolete by fixing URLs generated by AngularJS
|
||||
string.sub!('##', '#')
|
||||
URI(string)
|
||||
rescue URI::InvalidURIError
|
||||
nil
|
||||
end
|
||||
# TODO: make this operation obsolete by fixing URLs generated by AngularJS
|
||||
string.sub!('##', '#')
|
||||
URI(string)
|
||||
rescue URI::InvalidURIError
|
||||
nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
14
lib/spree/core/calculated_adjustments_decorator.rb
Normal file
14
lib/spree/core/calculated_adjustments_decorator.rb
Normal file
@@ -0,0 +1,14 @@
|
||||
module Spree
|
||||
module Core
|
||||
module CalculatedAdjustments
|
||||
module ClassMethods
|
||||
def calculated_adjustments_with_explicit_class_name
|
||||
calculated_adjustments_without_explicit_class_name
|
||||
# Class name is mis-inferred outside of Spree namespace
|
||||
has_one :calculator, as: :calculable, dependent: :destroy, class_name: 'Spree::Calculator'
|
||||
end
|
||||
alias_method_chain :calculated_adjustments, :explicit_class_name
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
26
lib/spree/core/controller_helpers/respond_with_decorator.rb
Normal file
26
lib/spree/core/controller_helpers/respond_with_decorator.rb
Normal file
@@ -0,0 +1,26 @@
|
||||
module ActionController
|
||||
class Base
|
||||
def respond_with(*resources, &block)
|
||||
raise "In order to use respond_with, first you need to declare the formats your " <<
|
||||
"controller responds to in the class level" if self.class.mimes_for_respond_to.empty?
|
||||
|
||||
if collector = retrieve_collector_from_mimes(&block)
|
||||
options = resources.size == 1 ? {} : resources.extract_options!
|
||||
|
||||
# Fix spree issues #3531 and #2210 (patch provided by leiyangyou)
|
||||
if defined_response = collector.response and !(Spree::BaseController.spree_responders[self.class.to_s.to_sym].try(:[], action_name.to_sym))
|
||||
if action = options.delete(:action)
|
||||
render :action => action
|
||||
else
|
||||
defined_response.call
|
||||
end
|
||||
else
|
||||
# The action name is needed for processing
|
||||
options.merge!(:action_name => action_name.to_sym)
|
||||
# If responder is not specified then pass in Spree::Responder
|
||||
(options.delete(:responder) || Spree::Responder).call(self, resources, options)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -6,7 +6,18 @@ Spree::Money.class_eval do
|
||||
end
|
||||
|
||||
def rounded
|
||||
@options[:no_cents] = true if @money.amount % 1 == 0
|
||||
@options[:no_cents] = true if @money.dollars % 1 == 0
|
||||
to_s
|
||||
end
|
||||
|
||||
def to_html(options = { :html => true })
|
||||
output = @money.format(@options.merge(options))
|
||||
if options[:html]
|
||||
# 1) prevent blank, breaking spaces
|
||||
# 2) prevent escaping of HTML character entities
|
||||
output = output.sub(" ", " ").html_safe
|
||||
end
|
||||
output
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -28,6 +28,7 @@ module Admin
|
||||
|
||||
spree_put :create, enterprise_params
|
||||
enterprise = Enterprise.find_by_name 'zzz'
|
||||
response.should redirect_to edit_admin_enterprise_path enterprise
|
||||
distributor_manager.enterprise_roles.where(enterprise_id: enterprise).first.should be
|
||||
end
|
||||
|
||||
@@ -37,15 +38,17 @@ module Admin
|
||||
|
||||
spree_put :create, enterprise_params
|
||||
enterprise = Enterprise.find_by_name 'zzz'
|
||||
response.should redirect_to edit_admin_enterprise_path enterprise
|
||||
admin_user.enterprise_roles.where(enterprise_id: enterprise).should be_empty
|
||||
end
|
||||
|
||||
it "overrides the owner_id submitted by the user unless current_user is super admin" do
|
||||
it "overrides the owner_id submitted by the user (when not super admin)" do
|
||||
controller.stub spree_current_user: distributor_manager
|
||||
enterprise_params[:enterprise][:owner_id] = user
|
||||
|
||||
spree_put :create, enterprise_params
|
||||
enterprise = Enterprise.find_by_name 'zzz'
|
||||
response.should redirect_to edit_admin_enterprise_path enterprise
|
||||
distributor_manager.enterprise_roles.where(enterprise_id: enterprise).first.should be
|
||||
end
|
||||
|
||||
@@ -58,6 +61,7 @@ module Admin
|
||||
|
||||
spree_put :create, enterprise_params
|
||||
enterprise = Enterprise.find_by_name 'zzz'
|
||||
response.should redirect_to edit_admin_enterprise_path enterprise
|
||||
enterprise.sells.should == 'any'
|
||||
end
|
||||
|
||||
@@ -68,6 +72,7 @@ module Admin
|
||||
|
||||
spree_put :create, enterprise_params
|
||||
enterprise = Enterprise.find_by_name 'zzz'
|
||||
response.should redirect_to edit_admin_enterprise_path enterprise
|
||||
enterprise.sells.should == 'none'
|
||||
end
|
||||
|
||||
@@ -80,6 +85,7 @@ module Admin
|
||||
|
||||
spree_put :create, enterprise_params
|
||||
enterprise = Enterprise.find_by_name 'zzz'
|
||||
response.should redirect_to edit_admin_enterprise_path enterprise
|
||||
enterprise.sells.should == 'none'
|
||||
end
|
||||
end
|
||||
|
||||
@@ -47,7 +47,7 @@ module Spree
|
||||
spree_delete :soft_delete, {variant_id: variant.to_param, product_id: product.to_param, format: :json}
|
||||
response.status.should == 204
|
||||
lambda { variant.reload }.should_not raise_error
|
||||
variant.deleted_at.should_not be_nil
|
||||
variant.deleted_at.should be_present
|
||||
end
|
||||
|
||||
it "is denied access to soft deleting another enterprises' variant" do
|
||||
|
||||
@@ -319,10 +319,6 @@ end
|
||||
|
||||
|
||||
FactoryGirl.modify do
|
||||
factory :base_product do
|
||||
unit_value 1
|
||||
unit_description ''
|
||||
end
|
||||
factory :product do
|
||||
primary_taxon { Spree::Taxon.first || FactoryGirl.create(:taxon) }
|
||||
end
|
||||
@@ -336,12 +332,15 @@ FactoryGirl.modify do
|
||||
primary_taxon { Spree::Taxon.first || FactoryGirl.create(:taxon) }
|
||||
on_hand 3
|
||||
|
||||
unit_value 1
|
||||
unit_description ''
|
||||
|
||||
variant_unit 'weight'
|
||||
variant_unit_scale 1
|
||||
variant_unit_name ''
|
||||
end
|
||||
|
||||
factory :base_variant do
|
||||
factory :variant do
|
||||
unit_value 1
|
||||
unit_description ''
|
||||
end
|
||||
|
||||
@@ -77,7 +77,7 @@ feature %q{
|
||||
|
||||
visit '/admin/enterprises'
|
||||
within "tr.enterprise-#{@enterprise.id}" do
|
||||
all("a", text: 'Edit Profile').first.click
|
||||
first("a", text: 'Edit Profile').trigger 'click'
|
||||
end
|
||||
|
||||
fill_in 'enterprise_name', :with => 'Eaterprises'
|
||||
@@ -210,8 +210,8 @@ feature %q{
|
||||
fill_in 'enterprise_producer_properties_attributes_0_value', with: "NASAA 12345"
|
||||
click_button 'Update'
|
||||
|
||||
# Then I should be returned to the enterprises page
|
||||
page.should have_selector '#listing_enterprises a', text: s.name
|
||||
# Then I should remain on the producer properties page
|
||||
expect(current_path).to eq main_app.admin_enterprise_producer_properties_path(s)
|
||||
|
||||
# And the producer should have the property
|
||||
s.producer_properties(true).count.should == 1
|
||||
@@ -233,8 +233,8 @@ feature %q{
|
||||
fill_in 'enterprise_producer_properties_attributes_0_value', with: "Shininess"
|
||||
click_button 'Update'
|
||||
|
||||
# Then I should be returned to the enterprises
|
||||
page.should have_selector '#listing_enterprises a', text: s.name
|
||||
# Then I should remain on the producer properties page
|
||||
expect(current_path).to eq main_app.admin_enterprise_producer_properties_path(s)
|
||||
|
||||
# And the property should be updated
|
||||
s.producer_properties(true).count.should == 1
|
||||
@@ -254,9 +254,10 @@ feature %q{
|
||||
# And I remove the property
|
||||
page.should have_field 'enterprise_producer_properties_attributes_0_property_name', with: 'Certified Organic'
|
||||
within("#spree_producer_property_#{pp.id}") { page.find('a.remove_fields').click }
|
||||
click_button 'Update'
|
||||
|
||||
# Then the property should have been removed
|
||||
page.should_not have_selector '#progress'
|
||||
expect(current_path).to eq main_app.admin_enterprise_producer_properties_path(s)
|
||||
page.should_not have_field 'enterprise_producer_properties_attributes_0_property_name', with: 'Certified Organic'
|
||||
s.producer_properties(true).should be_empty
|
||||
end
|
||||
@@ -438,7 +439,10 @@ feature %q{
|
||||
end
|
||||
|
||||
within("#spree_producer_property_#{pp.id}") { page.find('a.remove_fields').click }
|
||||
page.should_not have_selector '#progress'
|
||||
|
||||
click_button 'Update'
|
||||
|
||||
expect(page).to have_content 'Enterprise "First Supplier" has been successfully updated!'
|
||||
supplier1.producer_properties(true).should be_empty
|
||||
end
|
||||
end
|
||||
|
||||
@@ -409,11 +409,11 @@ feature %q{
|
||||
end
|
||||
|
||||
|
||||
scenario "updating many order cycle opening/closing times at once" do
|
||||
scenario "updating many order cycle opening/closing times at once", js: true do
|
||||
# Given three order cycles
|
||||
oc1 = create(:simple_order_cycle)
|
||||
oc2 = create(:simple_order_cycle)
|
||||
oc3 = create(:simple_order_cycle)
|
||||
oc3 = create(:simple_order_cycle, orders_open_at: Time.zone.local(2040, 12, 12, 12, 12, 12))
|
||||
|
||||
# When I go to the order cycles page
|
||||
login_to_admin_section
|
||||
@@ -430,7 +430,28 @@ feature %q{
|
||||
all('input').last.set '2040-12-01 12:00:03'
|
||||
end
|
||||
|
||||
# And I fill in a time using the datepicker
|
||||
within("tr.order-cycle-#{oc3.id}") do
|
||||
# When I trigger the datepicker
|
||||
find('img.ui-datepicker-trigger', match: :first).click
|
||||
end
|
||||
|
||||
within("#ui-datepicker-div") do
|
||||
# Then it should display the correct date/time
|
||||
expect(page).to have_selector 'span.ui-datepicker-month', text: 'DECEMBER'
|
||||
expect(page).to have_selector 'span.ui-datepicker-year', text: '2040'
|
||||
expect(page).to have_selector 'a.ui-state-active', text: '12'
|
||||
|
||||
# When I fill in a new date/time
|
||||
click_link '1'
|
||||
click_button 'Done'
|
||||
end
|
||||
|
||||
within("tr.order-cycle-#{oc3.id}") do
|
||||
# Then that date/time should appear on the form
|
||||
expect(all('input').first.value).to eq '2040-12-01 00:00'
|
||||
|
||||
# Manually fill out time
|
||||
all('input').first.set '2040-12-01 12:00:04'
|
||||
all('input').last.set '2040-12-01 12:00:05'
|
||||
end
|
||||
|
||||
@@ -39,6 +39,7 @@ feature %q{
|
||||
|
||||
click_button 'Create'
|
||||
|
||||
expect(current_path).to eq spree.bulk_edit_admin_products_path
|
||||
flash_message.should == 'Product "A new product !!!" has been successfully created!'
|
||||
product = Spree::Product.find_by_name('A new product !!!')
|
||||
product.supplier.should == @supplier
|
||||
@@ -56,22 +57,6 @@ feature %q{
|
||||
product.group_buy.should be_false
|
||||
product.master.option_values.map(&:name).should == ['5kg']
|
||||
product.master.options_text.should == "5kg"
|
||||
|
||||
# Distributors
|
||||
visit spree.product_distributions_admin_product_path(product)
|
||||
|
||||
check @distributors[0].name
|
||||
select2_select @enterprise_fees[0].name, :from => 'product_product_distributions_attributes_0_enterprise_fee_id'
|
||||
check @distributors[2].name
|
||||
select2_select @enterprise_fees[2].name, :from => 'product_product_distributions_attributes_2_enterprise_fee_id'
|
||||
|
||||
click_button 'Update'
|
||||
|
||||
product.reload
|
||||
product.distributors.should match_array [@distributors[0], @distributors[2]]
|
||||
|
||||
|
||||
product.product_distributions.map { |pd| pd.enterprise_fee }.should match_array [@enterprise_fees[0], @enterprise_fees[2]]
|
||||
end
|
||||
|
||||
scenario "making a product into a group buy product" do
|
||||
@@ -185,7 +170,7 @@ feature %q{
|
||||
|
||||
scenario "deleting product properties", js: true do
|
||||
# Given a product with a property
|
||||
p = create(:simple_product, supplier: @supplier)
|
||||
p = create(:simple_product, supplier: @supplier2)
|
||||
p.set_property('fooprop', 'fooval')
|
||||
|
||||
# When I navigate to the product properties page
|
||||
@@ -195,11 +180,12 @@ feature %q{
|
||||
|
||||
# And I delete the property
|
||||
page.all('a.remove_fields').first.click
|
||||
wait_until { p.reload.property('fooprop').nil? }
|
||||
click_button 'Update'
|
||||
|
||||
# Then the property should have been deleted
|
||||
page.should_not have_field 'product_product_properties_attributes_0_property_name', with: 'fooprop'
|
||||
page.should_not have_field 'product_product_properties_attributes_0_value', with: 'fooval'
|
||||
expect(p.reload.property('fooprop')).to be_nil
|
||||
end
|
||||
|
||||
|
||||
|
||||
@@ -3,23 +3,23 @@ require 'spec_helper'
|
||||
module Spree
|
||||
module Admin
|
||||
describe NavigationHelper do
|
||||
describe "klass_for" do
|
||||
it "returns the class when present" do
|
||||
helper.klass_for('products').should == Spree::Product
|
||||
end
|
||||
# describe "klass_for" do
|
||||
# it "returns the class when present" do
|
||||
# helper.klass_for('products').should == Spree::Product
|
||||
# end
|
||||
|
||||
it "returns a symbol when there's no available class" do
|
||||
helper.klass_for('reports').should == :report
|
||||
end
|
||||
# it "returns a symbol when there's no available class" do
|
||||
# helper.klass_for('reports').should == :report
|
||||
# end
|
||||
|
||||
it "returns :overview for the dashboard" do
|
||||
helper.klass_for('dashboard').should == :overview
|
||||
end
|
||||
# it "returns :overview for the dashboard" do
|
||||
# helper.klass_for('dashboard').should == :overview
|
||||
# end
|
||||
|
||||
it "returns Spree::Order for bulk_order_management" do
|
||||
helper.klass_for('bulk_order_management').should == Spree::Order
|
||||
end
|
||||
end
|
||||
# it "returns Spree::Order for bulk_order_management" do
|
||||
# helper.klass_for('bulk_order_management').should == Spree::Order
|
||||
# end
|
||||
# end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -37,25 +37,14 @@ describe "Enterprises service", ->
|
||||
expect(result).toDeepEqual response
|
||||
|
||||
describe "when params are passed", ->
|
||||
describe "where includeBlank param is truthy", ->
|
||||
beforeEach ->
|
||||
params = {includeBlank: true, someParam: 'someVal'}
|
||||
$httpBackend.expectGET('/admin/enterprises.json?someParam=someVal').respond 200, response
|
||||
result = Enterprises.index(params)
|
||||
$httpBackend.flush()
|
||||
beforeEach ->
|
||||
params = { someParam: 'someVal'}
|
||||
$httpBackend.expectGET('/admin/enterprises.json?someParam=someVal').respond 200, response
|
||||
result = Enterprises.index(params)
|
||||
$httpBackend.flush()
|
||||
|
||||
it "returns an array of enterprises, with a blank option appended to the beginning", ->
|
||||
expect(result).toDeepEqual [{id: '0', name: 'All'} ,{ id: 5, name: 'Enterprise 1'}]
|
||||
|
||||
describe "where includeBlank param is falsey", ->
|
||||
beforeEach ->
|
||||
params = {includeBlank: false, someParam: 'someVal'}
|
||||
$httpBackend.expectGET('/admin/enterprises.json?someParam=someVal').respond 200, response
|
||||
result = Enterprises.index(params)
|
||||
$httpBackend.flush()
|
||||
|
||||
it "returns an array of enterprises, with a blank option appended to the beginning", ->
|
||||
expect(result).toDeepEqual response
|
||||
it "returns an array of enterprises", ->
|
||||
expect(result).toDeepEqual response
|
||||
|
||||
|
||||
describe "#save", ->
|
||||
|
||||
@@ -63,17 +63,17 @@ describe "LineItemsCtrl", ->
|
||||
$timeout.flush()
|
||||
|
||||
describe "initialisation", ->
|
||||
it "gets suppliers, adds a blank option as the first in the list", ->
|
||||
expect(scope.suppliers).toDeepEqual [ { id : '0', name : 'All' }, supplier ]
|
||||
it "gets suppliers", ->
|
||||
expect(scope.suppliers).toDeepEqual [supplier ]
|
||||
|
||||
it "gets distributors, adds a blank option as the first in the list", ->
|
||||
expect(scope.distributors).toDeepEqual [ { id : '0', name : 'All' }, distributor ]
|
||||
it "gets distributors", ->
|
||||
expect(scope.distributors).toDeepEqual [ distributor ]
|
||||
|
||||
it "stores enterprises in an list that is accessible by id", ->
|
||||
expect(Enterprises.enterprisesByID[1]).toDeepEqual supplier
|
||||
|
||||
it "gets order cycles, adds a blank option as the first in the list", ->
|
||||
expect(scope.orderCycles).toDeepEqual [ { id : '0', name : 'All' }, orderCycle ]
|
||||
it "gets order cycles", ->
|
||||
expect(scope.orderCycles).toDeepEqual [ orderCycle ]
|
||||
|
||||
it "gets orders, with dereferenced order cycles and distributors", ->
|
||||
expect(scope.orders).toDeepEqual [ { id: 9, order_cycle: orderCycle, distributor: distributor, number: "R123456" } ]
|
||||
@@ -85,9 +85,9 @@ describe "LineItemsCtrl", ->
|
||||
expect(scope.RequestMonitor.loading).toBe false
|
||||
|
||||
it "resets the select filters", ->
|
||||
expect(scope.distributorFilter).toBe '0'
|
||||
expect(scope.supplierFilter).toBe '0'
|
||||
expect(scope.orderCycleFilter).toBe '0'
|
||||
expect(scope.distributorFilter).toBe 0
|
||||
expect(scope.supplierFilter).toBe 0
|
||||
expect(scope.orderCycleFilter).toBe 0
|
||||
expect(scope.quickSearch).toBe = ""
|
||||
|
||||
it "resets the form state to pristine", ->
|
||||
|
||||
@@ -7,9 +7,6 @@ describe 'convert number to localised currency ', ->
|
||||
symbol_position: "before"
|
||||
currency: "D"
|
||||
hide_cents: "false"
|
||||
# Not used yet...
|
||||
# decimal_mark: "."
|
||||
# thousands_separator: ","
|
||||
module 'Darkswarm'
|
||||
module ($provide)->
|
||||
$provide.value "currencyConfig", currencyconfig
|
||||
@@ -38,5 +35,3 @@ describe 'convert number to localised currency ', ->
|
||||
it "can hide cents", ->
|
||||
currencyconfig.hide_cents = "true"
|
||||
expect(filter(5)).toEqual "$5"
|
||||
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
require 'spec_helper'
|
||||
require 'open_food_network/enterprise_fee_applicator'
|
||||
|
||||
module OpenFoodNetwork
|
||||
|
||||
@@ -149,13 +149,13 @@ module Spree
|
||||
|
||||
it "should be able to read/write their enterprises' products and variants" do
|
||||
should have_ability([:admin, :read, :update, :product_distributions, :bulk_edit, :bulk_update, :clone, :destroy], for: p1)
|
||||
should have_ability([:admin, :index, :read, :edit, :update, :search, :destroy], for: p1.master)
|
||||
should have_ability([:admin, :index, :read, :edit, :update, :search, :destroy, :delete], for: p1.master)
|
||||
end
|
||||
|
||||
it "should be able to read/write related enterprises' products and variants with manage_products permission" do
|
||||
er_ps
|
||||
should have_ability([:admin, :read, :update, :product_distributions, :bulk_edit, :bulk_update, :clone, :destroy], for: p_related)
|
||||
should have_ability([:admin, :index, :read, :edit, :update, :search, :destroy], for: p_related.master)
|
||||
should have_ability([:admin, :index, :read, :edit, :update, :search, :destroy, :delete], for: p_related.master)
|
||||
end
|
||||
|
||||
it "should not be able to read/write other enterprises' products and variants" do
|
||||
@@ -173,7 +173,7 @@ module Spree
|
||||
|
||||
it "should be able to read/write their enterprises' product variants" do
|
||||
should have_ability([:create], for: Spree::Variant)
|
||||
should have_ability([:admin, :index, :read, :create, :edit, :search, :update, :destroy], for: p1.master)
|
||||
should have_ability([:admin, :index, :read, :create, :edit, :search, :update, :destroy, :delete], for: p1.master)
|
||||
end
|
||||
|
||||
it "should not be able to read/write other enterprises' product variants" do
|
||||
|
||||
10
spec/models/spree/calculator/flat_percent_item_total_spec.rb
Normal file
10
spec/models/spree/calculator/flat_percent_item_total_spec.rb
Normal file
@@ -0,0 +1,10 @@
|
||||
describe Spree::Calculator::FlatPercentItemTotal do
|
||||
let(:calculator) { Spree::Calculator::FlatPercentItemTotal.new }
|
||||
let(:line_item) { mock_model(Spree::LineItem, amount: 10) }
|
||||
|
||||
before { calculator.stub :preferred_flat_percent => 10 }
|
||||
|
||||
it "should compute amount correctly for a single line item" do
|
||||
calculator.compute(line_item).should == 1.0
|
||||
end
|
||||
end
|
||||
17
spec/models/spree/calculator/flexi_rate_spec.rb
Normal file
17
spec/models/spree/calculator/flexi_rate_spec.rb
Normal file
@@ -0,0 +1,17 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe Spree::Calculator::FlexiRate do
|
||||
let(:calculator) { Spree::Calculator::FlexiRate.new }
|
||||
let(:line_item) { mock_model(Spree::LineItem, amount: 10, quantity: 4) }
|
||||
|
||||
describe "computing for a single line item" do
|
||||
it "returns the first item rate" do
|
||||
calculator.stub preferred_first_item: 1.0
|
||||
calculator.compute(line_item).round(2).should == 1.0
|
||||
end
|
||||
end
|
||||
|
||||
it "allows creation of new object with all the attributes" do
|
||||
Spree::Calculator::FlexiRate.new(preferred_first_item: 1, preferred_additional_item: 1, preferred_max_items: 1)
|
||||
end
|
||||
end
|
||||
12
spec/models/spree/calculator/per_item_spec.rb
Normal file
12
spec/models/spree/calculator/per_item_spec.rb
Normal file
@@ -0,0 +1,12 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe Spree::Calculator::PerItem do
|
||||
let(:calculator) { Spree::Calculator::PerItem.new(preferred_amount: 10) }
|
||||
let(:shipping_calculable) { double(:calculable) }
|
||||
let(:line_item) { double(:line_item, quantity: 5, product: double(:product)) }
|
||||
|
||||
it "correctly calculates on a single line item object" do
|
||||
calculator.stub(calculable: shipping_calculable)
|
||||
calculator.compute(line_item).to_f.should == 50 # 5 x 10
|
||||
end
|
||||
end
|
||||
17
spec/models/spree/calculator/price_sack_spec.rb
Normal file
17
spec/models/spree/calculator/price_sack_spec.rb
Normal file
@@ -0,0 +1,17 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe Spree::Calculator::PriceSack do
|
||||
let(:calculator) do
|
||||
calculator = Spree::Calculator::PriceSack.new
|
||||
calculator.preferred_minimal_amount = 5
|
||||
calculator.preferred_normal_amount = 10
|
||||
calculator.preferred_discount_amount = 1
|
||||
calculator
|
||||
end
|
||||
|
||||
let(:line_item) { stub_model(Spree::LineItem, price: 1, quantity: 2) }
|
||||
|
||||
it "computes with a line item object" do
|
||||
calculator.compute(line_item)
|
||||
end
|
||||
end
|
||||
@@ -585,10 +585,10 @@ module Spree
|
||||
describe "finding products in stock for a particular distribution" do
|
||||
it "returns on-demand products" do
|
||||
p = create(:simple_product, on_demand: true)
|
||||
p.master.update_attribute(:count_on_hand, 0)
|
||||
p.variants.first.update_attributes!(count_on_hand: 0, on_demand: true)
|
||||
d = create(:distributor_enterprise)
|
||||
oc = create(:simple_order_cycle, distributors: [d])
|
||||
oc.exchanges.outgoing.first.variants << p.master
|
||||
oc.exchanges.outgoing.first.variants << p.variants.first
|
||||
|
||||
p.should have_stock_for_distribution(oc, d)
|
||||
end
|
||||
|
||||
@@ -78,7 +78,7 @@ module WebHelper
|
||||
end
|
||||
|
||||
def flash_message
|
||||
find('.flash').text.strip
|
||||
find('.flash', visible: false).text.strip
|
||||
end
|
||||
|
||||
def errors
|
||||
|
||||
Reference in New Issue
Block a user