mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-03-01 02:03:22 +00:00
Merge branch 'master' into bom
This commit is contained in:
3
Gemfile
3
Gemfile
@@ -21,6 +21,7 @@ gem 'bugsnag'
|
||||
gem 'newrelic_rpm'
|
||||
gem 'haml'
|
||||
gem 'sass', "~> 3.2"
|
||||
gem 'sass-rails', '~> 3.2.3', groups: [:default, :assets]
|
||||
gem 'aws-sdk'
|
||||
gem 'db2fog'
|
||||
gem 'andand'
|
||||
@@ -39,7 +40,6 @@ gem 'rack-ssl', :require => 'rack/ssl'
|
||||
# Gems used only for assets and not required
|
||||
# in production environments by default.
|
||||
group :assets do
|
||||
gem 'sass-rails', '~> 3.2.3'
|
||||
gem 'compass-rails'
|
||||
gem 'coffee-rails', '~> 3.2.1'
|
||||
|
||||
@@ -49,6 +49,7 @@ group :assets do
|
||||
gem 'uglifier', '>= 1.0.3'
|
||||
|
||||
gem 'turbo-sprockets-rails3'
|
||||
gem 'foundation-icons-sass-rails'
|
||||
|
||||
end
|
||||
gem "foundation-rails"
|
||||
|
||||
@@ -262,6 +262,9 @@ GEM
|
||||
nokogiri (~> 1.5)
|
||||
ruby-hmac
|
||||
formatador (0.2.4)
|
||||
foundation-icons-sass-rails (3.0.0)
|
||||
railties (>= 3.1.1)
|
||||
sass-rails (>= 3.1.1)
|
||||
foundation-rails (5.2.1.0)
|
||||
railties (>= 3.1.0)
|
||||
sass (>= 3.2.0)
|
||||
@@ -509,6 +512,7 @@ DEPENDENCIES
|
||||
eaterprises_feature!
|
||||
factory_girl_rails
|
||||
faker
|
||||
foundation-icons-sass-rails
|
||||
foundation-rails
|
||||
foundation_rails_helper!
|
||||
geocoder
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
[](http://ci.openfood.com.au:8080/job/openfoodweb%20-%20tests/)
|
||||
[](https://codeclimate.com/github/openfoodfoundation/openfoodnetwork)
|
||||
|
||||
# Open Food Network
|
||||
|
||||
Connect suppliers (ie. farmers), distributors (ie. co-ops) and
|
||||
|
||||
@@ -9,9 +9,15 @@ angular.module('order_cycle', ['ngResource'])
|
||||
$scope.loaded = ->
|
||||
Enterprise.loaded && EnterpriseFee.loaded
|
||||
|
||||
$scope.suppliedVariants = (enterprise_id) ->
|
||||
Enterprise.suppliedVariants(enterprise_id)
|
||||
|
||||
$scope.exchangeSelectedVariants = (exchange) ->
|
||||
OrderCycle.exchangeSelectedVariants(exchange)
|
||||
|
||||
$scope.setExchangeVariants = (exchange, variants, selected) ->
|
||||
OrderCycle.setExchangeVariants(exchange, variants, selected)
|
||||
|
||||
$scope.enterpriseTotalVariants = (enterprise) ->
|
||||
Enterprise.totalVariants(enterprise)
|
||||
|
||||
@@ -83,9 +89,15 @@ angular.module('order_cycle', ['ngResource'])
|
||||
$scope.loaded = ->
|
||||
Enterprise.loaded && EnterpriseFee.loaded && OrderCycle.loaded
|
||||
|
||||
$scope.suppliedVariants = (enterprise_id) ->
|
||||
Enterprise.suppliedVariants(enterprise_id)
|
||||
|
||||
$scope.exchangeSelectedVariants = (exchange) ->
|
||||
OrderCycle.exchangeSelectedVariants(exchange)
|
||||
|
||||
$scope.setExchangeVariants = (exchange, variants, selected) ->
|
||||
OrderCycle.setExchangeVariants(exchange, variants, selected)
|
||||
|
||||
$scope.enterpriseTotalVariants = (enterprise) ->
|
||||
Enterprise.totalVariants(enterprise)
|
||||
|
||||
@@ -175,6 +187,9 @@ angular.module('order_cycle', ['ngResource'])
|
||||
toggleProducts: (exchange) ->
|
||||
exchange.showProducts = !exchange.showProducts
|
||||
|
||||
setExchangeVariants: (exchange, variants, selected) ->
|
||||
exchange.variants[variant] = selected for variant in variants
|
||||
|
||||
addSupplier: (new_supplier_id) ->
|
||||
this.order_cycle.incoming_exchanges.push({enterprise_id: new_supplier_id, incoming: true, active: true, variants: {}, enterprise_fees: []})
|
||||
|
||||
@@ -271,12 +286,27 @@ angular.module('order_cycle', ['ngResource'])
|
||||
console.log('Failed to update order cycle')
|
||||
|
||||
dataForSubmit: ->
|
||||
data = angular.extend({}, this.order_cycle)
|
||||
data = this.deepCopy()
|
||||
data = this.removeInactiveExchanges(data)
|
||||
data = this.translateCoordinatorFees(data)
|
||||
data = this.translateExchangeFees(data)
|
||||
data
|
||||
|
||||
deepCopy: ->
|
||||
data = angular.extend({}, this.order_cycle)
|
||||
|
||||
# Copy exchanges
|
||||
data.incoming_exchanges = (angular.extend {}, exchange for exchange in this.order_cycle.incoming_exchanges) if this.order_cycle.incoming_exchanges?
|
||||
data.outgoing_exchanges = (angular.extend {}, exchange for exchange in this.order_cycle.outgoing_exchanges) if this.order_cycle.outgoing_exchanges?
|
||||
|
||||
# Copy exchange fees
|
||||
all_exchanges = (data.incoming_exchanges || []) + (data.outgoing_exchanges || [])
|
||||
for exchange in all_exchanges
|
||||
if exchange.enterprise_fees?
|
||||
exchange.enterprise_fees = (angular.extend {}, fee for fee in exchange.enterprise_fees)
|
||||
|
||||
data
|
||||
|
||||
removeInactiveExchanges: (order_cycle) ->
|
||||
order_cycle.incoming_exchanges =
|
||||
(exchange for exchange in order_cycle.incoming_exchanges when exchange.active)
|
||||
@@ -322,6 +352,16 @@ angular.module('order_cycle', ['ngResource'])
|
||||
|
||||
this.enterprises
|
||||
|
||||
suppliedVariants: (enterprise_id) ->
|
||||
vs = (this.variantsOf(product) for product in this.enterprises[enterprise_id].supplied_products)
|
||||
[].concat vs...
|
||||
|
||||
variantsOf: (product) ->
|
||||
if product.variants.length > 0
|
||||
variant.id for variant in product.variants
|
||||
else
|
||||
[product.master_id]
|
||||
|
||||
totalVariants: (enterprise) ->
|
||||
numVariants = 0
|
||||
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
window.AccountSidebarCtrl = Darkswarm.controller "AccountSidebarCtrl", ($scope, $http, $location, SpreeUser, Navigation) ->
|
||||
$scope.path = "/account"
|
||||
Navigation.paths.push $scope.path
|
||||
|
||||
$scope.active = ->
|
||||
$location.path() == $scope.path
|
||||
|
||||
$scope.select = ->
|
||||
Navigation.navigate($scope.path)
|
||||
|
||||
$scope.emptyCart = (href, ev)->
|
||||
console.log href
|
||||
if $(ev.delegateTarget).hasClass "empties-cart"
|
||||
location.href = href if confirm "Changing your Hub will clear your cart."
|
||||
else
|
||||
location.href = href
|
||||
@@ -1,12 +1,14 @@
|
||||
window.ForgotSidebarCtrl = Darkswarm.controller "ForgotSidebarCtrl", ($scope, $http, $location, SpreeUser) ->
|
||||
window.ForgotSidebarCtrl = Darkswarm.controller "ForgotSidebarCtrl", ($scope, $http, $location, SpreeUser, Navigation) ->
|
||||
$scope.spree_user = SpreeUser.spree_user
|
||||
$scope.path = "/forgot"
|
||||
$scope.sent = false
|
||||
Navigation.paths.push $scope.path
|
||||
|
||||
$scope.active = ->
|
||||
$location.path() == '/forgot'
|
||||
$location.path() == $scope.path
|
||||
|
||||
$scope.select = ->
|
||||
$location.path("/forgot")
|
||||
Navigation.navigate($scope.path)
|
||||
|
||||
$scope.submit = ->
|
||||
if $scope.spree_user.email != null
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
window.LoginSidebarCtrl = Darkswarm.controller "LoginSidebarCtrl", ($scope, $http, $location, SpreeUser) ->
|
||||
window.LoginSidebarCtrl = Darkswarm.controller "LoginSidebarCtrl", ($scope, $http, $location, SpreeUser, Navigation) ->
|
||||
$scope.spree_user = SpreeUser.spree_user
|
||||
$scope.path = "/login"
|
||||
Navigation.paths.push $scope.path
|
||||
|
||||
$scope.active = ->
|
||||
$location.path() == '/login'
|
||||
$location.path() == $scope.path
|
||||
|
||||
$scope.select = ->
|
||||
$location.path("/login")
|
||||
Navigation.navigate($scope.path)
|
||||
|
||||
|
||||
$scope.submit = ->
|
||||
$http.post("/user/spree_user/sign_in", {spree_user: $scope.spree_user}).success (data)->
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
window.MenuCtrl = Darkswarm.controller "MenuCtrl", ($scope, $location) ->
|
||||
window.MenuCtrl = Darkswarm.controller "MenuCtrl", ($scope, Navigation) ->
|
||||
|
||||
$scope.toggleLogin = ->
|
||||
if $location.path() == "/login"
|
||||
$location.path("/")
|
||||
else
|
||||
$location.path("login")
|
||||
Navigation.navigate "/login"
|
||||
|
||||
$scope.toggleSignup = ->
|
||||
if $location.path() == "/signup"
|
||||
$location.path("/")
|
||||
else
|
||||
$location.path("signup")
|
||||
Navigation.navigate "/signup"
|
||||
|
||||
$scope.toggleSignup = ->
|
||||
Navigation.navigate "/signup"
|
||||
|
||||
$scope.toggle = (path = null)->
|
||||
Navigation.navigate(path)
|
||||
|
||||
@@ -1,5 +1,15 @@
|
||||
Darkswarm.controller "OrderCycleCtrl", ($scope, $rootScope, OrderCycle) ->
|
||||
Darkswarm.controller "OrderCycleCtrl", ($scope, $rootScope, OrderCycle, $timeout) ->
|
||||
$scope.order_cycle = OrderCycle.order_cycle
|
||||
$scope.OrderCycle = OrderCycle
|
||||
|
||||
$scope.changeOrderCycle = ->
|
||||
OrderCycle.push_order_cycle()
|
||||
$timeout ->
|
||||
$("#order_cycle_id").trigger("closeTrigger")
|
||||
|
||||
# Timeout forces this to be evaluated after everything is loaded
|
||||
# This is a hack. We should probably write our own "popover" directive
|
||||
# That takes an expression instead of a trigger, and binds to that
|
||||
$timeout =>
|
||||
if !$scope.OrderCycle.selected()
|
||||
$("#order_cycle_id").trigger("openTrigger")
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
window.SidebarCtrl = Darkswarm.controller "SidebarCtrl", ($scope, $location) ->
|
||||
$scope.sidebarPaths = ["/login", "/signup", "/forgot", "/account"]
|
||||
|
||||
$scope.active = ->
|
||||
$location.path() in ["/login", "/signup", "/forgot"]
|
||||
$location.path() in $scope.sidebarPaths
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
window.SignupSidebarCtrl = Darkswarm.controller "SignupSidebarCtrl", ($scope, $http, $location, SpreeUser) ->
|
||||
window.SignupSidebarCtrl = Darkswarm.controller "SignupSidebarCtrl", ($scope, $http, $location, SpreeUser, Navigation) ->
|
||||
$scope.spree_user = SpreeUser.spree_user
|
||||
$scope.path = "/signup"
|
||||
Navigation.paths.push $scope.path
|
||||
$scope.errors =
|
||||
email: null
|
||||
password: null
|
||||
|
||||
$scope.active = ->
|
||||
$location.path() == '/signup'
|
||||
$location.path() == $scope.path
|
||||
|
||||
$scope.select = ->
|
||||
$location.path("/signup")
|
||||
Navigation.navigate($scope.path)
|
||||
|
||||
$scope.submit = ->
|
||||
$http.post("/user/spree_user", {spree_user: $scope.spree_user}).success (data)->
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
window.Darkswarm = angular.module("Darkswarm", ["ngResource", "filters", 'mm.foundation']).config ($httpProvider) ->
|
||||
window.Darkswarm = angular.module("Darkswarm", ["ngResource", "filters", 'mm.foundation']).config ($httpProvider, $tooltipProvider) ->
|
||||
$httpProvider.defaults.headers.post['X-CSRF-Token'] = $('meta[name="csrf-token"]').attr('content')
|
||||
$httpProvider.defaults.headers['common']['X-Requested-With'] = 'XMLHttpRequest'
|
||||
$httpProvider.defaults.headers.common.Accept = "application/json, text/javascript, */*"
|
||||
|
||||
# This allows us to trigger these two events on tooltips
|
||||
$tooltipProvider.setTriggers( 'openTrigger': 'closeTrigger' )
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
Darkswarm.factory 'Navigation', ($location) ->
|
||||
new class Navigation
|
||||
paths: []
|
||||
path: null
|
||||
|
||||
navigate: (path = false)->
|
||||
@path = path || @path || @paths[0]
|
||||
|
||||
if $location.path() == @path
|
||||
$location.path("/")
|
||||
else
|
||||
$location.path(@path)
|
||||
@@ -7,9 +7,8 @@ Darkswarm.factory 'OrderCycle', ($resource, Product, orderCycleData) ->
|
||||
Product.update()
|
||||
|
||||
@orders_close_at: ->
|
||||
if @order_cycle
|
||||
if @selected()
|
||||
@order_cycle.orders_close_at
|
||||
else
|
||||
""
|
||||
|
||||
@selected: ->
|
||||
@order_cycle != null
|
||||
@order_cycle != null and !$.isEmptyObject(@order_cycle) and @order_cycle.orders_close_at != undefined
|
||||
|
||||
@@ -2,10 +2,11 @@ Darkswarm.factory 'Product', ($resource) ->
|
||||
new class Product
|
||||
data: {
|
||||
products: null
|
||||
loading: true
|
||||
}
|
||||
update: ->
|
||||
@data.products = $resource("/shop/products").query =>
|
||||
#console.log @products
|
||||
@data.loading = false
|
||||
@data
|
||||
all: ->
|
||||
@data.products || @update()
|
||||
|
||||
@@ -2058,7 +2058,7 @@ angular.module( 'mm.foundation.tour', [ 'mm.foundation.position', 'mm.foundation
|
||||
};
|
||||
}])
|
||||
|
||||
.directive( 'stepText', [ '$position', '$tooltip', '$tour', '$window', function ( $position, $tooltip, $tour, $window ) {
|
||||
.directive( 'step', [ '$position', '$tooltip', '$tour', '$window', function ( $position, $tooltip, $tour, $window ) {
|
||||
function isElementInViewport( element ) {
|
||||
var rect = element[0].getBoundingClientRect();
|
||||
|
||||
@@ -2092,6 +2092,7 @@ angular.module( 'mm.foundation.tour', [ 'mm.foundation.position', 'mm.foundation
|
||||
return $tooltip( 'step', 'step', show );
|
||||
}]);
|
||||
|
||||
|
||||
angular.module('mm.foundation.typeahead', ['mm.foundation.position', 'mm.foundation.bindHtml'])
|
||||
|
||||
/**
|
||||
@@ -2602,7 +2603,7 @@ angular.module("template/tour/tour.html", []).run(["$templateCache", function($t
|
||||
" <h4 ng-bind=\"title\" ng-show=\"title\"></h4>\n" +
|
||||
" <p ng-bind=\"content\"></p>\n" +
|
||||
" <a class=\"small button joyride-next-tip\" ng-show=\"!isLastStep()\" ng-click=\"nextStep()\">Next</a>\n" +
|
||||
" <a class=\"small button joyride-next-tip\" ng-show=\"isLastStep()\" ng-click=\"endTour()\">End</a>\n" +
|
||||
//" <a class=\"small button joyride-next-tip\" ng-show=\"isLastStep()\" ng-click=\"endTour()\">Close</a>\n" +
|
||||
" <a class=\"joyride-close-tip\" ng-click=\"endTour()\">×</a>\n" +
|
||||
" </div>\n" +
|
||||
"</div>\n" +
|
||||
|
||||
@@ -52,6 +52,11 @@ form.order_cycle {
|
||||
border-bottom: 2px solid #C3D9FF;
|
||||
}
|
||||
|
||||
.exchange-select-all-variants {
|
||||
clear: both;
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
.exchange-product {
|
||||
float: left;
|
||||
overflow: auto;
|
||||
|
||||
@@ -7,3 +7,4 @@
|
||||
*= require foundation
|
||||
*= require_tree .
|
||||
*/
|
||||
@import 'foundation-icons';
|
||||
|
||||
@@ -1,6 +1,20 @@
|
||||
/*body { background: #ff0000; }*/
|
||||
nav.top-bar
|
||||
margin-bottom: 0px
|
||||
a.icon
|
||||
&:hover
|
||||
text-decoration: none
|
||||
height: 45px
|
||||
color: white
|
||||
i
|
||||
font-size: 29px
|
||||
line-height: 45px
|
||||
span
|
||||
font-size: 13px
|
||||
display: inline-block
|
||||
line-height: 45px
|
||||
height: 45px
|
||||
vertical-align: top
|
||||
|
||||
body > section[role='main']
|
||||
padding: 0px
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
// We can't import foundation components?
|
||||
// See https://github.com/zurb/foundation/issues/3855#issuecomment-30372252
|
||||
|
||||
|
||||
@import "foundation"
|
||||
@import "variables"
|
||||
@import "components/global"
|
||||
@import "components/buttons"
|
||||
@@ -20,3 +22,12 @@
|
||||
|
||||
.tabs dd a
|
||||
padding: 0.5em 1em
|
||||
|
||||
#account
|
||||
dl
|
||||
@include clearfix
|
||||
dt, dd
|
||||
display: inline-block
|
||||
|
||||
p > strong
|
||||
display: block
|
||||
|
||||
@@ -30,7 +30,6 @@ class Shop::CheckoutController < Spree::CheckoutController
|
||||
|
||||
if @order.state == "complete" || @order.completed?
|
||||
flash.notice = t(:order_processed_successfully)
|
||||
flash[:commerce_tracking] = "nothing special"
|
||||
respond_with(@order, :location => order_path(@order))
|
||||
else
|
||||
clear_ship_address
|
||||
|
||||
@@ -10,7 +10,7 @@ class Shop::ShopController < BaseController
|
||||
def products
|
||||
unless @products = current_order_cycle.andand
|
||||
.valid_products_distributed_by(current_distributor).andand
|
||||
.select { |p| p.has_stock_for_distribution?(current_order_cycle, current_distributor) }.andand
|
||||
.select { |p| !p.deleted? && p.has_stock_for_distribution?(current_order_cycle, current_distributor) }.andand
|
||||
.sort_by {|p| p.name }
|
||||
|
||||
render json: "", status: 404
|
||||
|
||||
3
app/controllers/spree/users_controller_decorator.rb
Normal file
3
app/controllers/spree/users_controller_decorator.rb
Normal file
@@ -0,0 +1,3 @@
|
||||
Spree::UsersController.class_eval do
|
||||
layout 'darkswarm'
|
||||
end
|
||||
@@ -1,4 +1,5 @@
|
||||
class UserPasswordsController < Spree::UserPasswordsController
|
||||
layout 'darkswarm'
|
||||
|
||||
def create
|
||||
self.resource = resource_class.send_reset_password_instructions(params[resource_name])
|
||||
|
||||
@@ -18,4 +18,8 @@ module SharedHelper
|
||||
[]
|
||||
end
|
||||
end
|
||||
|
||||
def enterprise_user?
|
||||
spree_current_user.andand.enterprises.count > 0
|
||||
end
|
||||
end
|
||||
|
||||
@@ -14,5 +14,13 @@ module Spree
|
||||
def alternative_available_distributors(order)
|
||||
DistributionChangeValidator.new(order).available_distributors(Enterprise.all) - [order.distributor]
|
||||
end
|
||||
|
||||
def last_completed_order
|
||||
spree_current_user.orders.complete.last
|
||||
end
|
||||
|
||||
def cart_count
|
||||
current_order.andand.line_items.count || 0
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
8
app/mailers/spree/user_mailer_decorator.rb
Normal file
8
app/mailers/spree/user_mailer_decorator.rb
Normal file
@@ -0,0 +1,8 @@
|
||||
Spree::UserMailer.class_eval do
|
||||
|
||||
def signup_confirmation(user)
|
||||
@user = user
|
||||
mail(:to => user.email, :from => from_address,
|
||||
:subject => 'Welcome to ' + Spree::Config[:site_name])
|
||||
end
|
||||
end
|
||||
@@ -11,7 +11,7 @@ class Exchange < ActiveRecord::Base
|
||||
has_many :enterprise_fees, :through => :exchange_fees
|
||||
|
||||
validates_presence_of :order_cycle, :sender, :receiver
|
||||
validates_uniqueness_of :sender_id, :scope => [:order_cycle_id, :receiver_id]
|
||||
validates_uniqueness_of :sender_id, :scope => [:order_cycle_id, :receiver_id, :incoming]
|
||||
|
||||
accepts_nested_attributes_for :variants
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
module Spree
|
||||
Adjustment.class_eval do
|
||||
has_one :metadata, class_name: 'AdjustmentMetadata'
|
||||
has_one :metadata, class_name: 'AdjustmentMetadata', dependent: :destroy
|
||||
|
||||
scope :enterprise_fee, where(originator_type: 'EnterpriseFee')
|
||||
end
|
||||
|
||||
@@ -85,6 +85,7 @@ Spree::Order.class_eval do
|
||||
def set_order_cycle!(order_cycle)
|
||||
self.order_cycle = order_cycle
|
||||
self.distributor = nil unless order_cycle.nil? || order_cycle.has_distributor?(distributor)
|
||||
self.empty!
|
||||
save!
|
||||
end
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ Spree.user_class.class_eval do
|
||||
accepts_nested_attributes_for :enterprise_roles, :allow_destroy => true
|
||||
|
||||
attr_accessible :enterprise_ids, :enterprise_roles_attributes
|
||||
after_create :send_signup_confirmation
|
||||
|
||||
def build_enterprise_roles
|
||||
Enterprise.all.each do |enterprise|
|
||||
@@ -14,4 +15,8 @@ Spree.user_class.class_eval do
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def send_signup_confirmation
|
||||
Spree::UserMailer.signup_confirmation(self).deliver
|
||||
end
|
||||
end
|
||||
|
||||
@@ -12,6 +12,7 @@ Spree::Variant.class_eval do
|
||||
if: -> v { v.product.variant_unit.present? && v.unit_value.nil? },
|
||||
unless: :is_master
|
||||
|
||||
before_validation :update_weight_from_unit_value
|
||||
after_save :update_units
|
||||
|
||||
scope :in_stock, where('spree_variants.count_on_hand > 0 OR spree_variants.on_demand=?', true)
|
||||
@@ -43,6 +44,10 @@ Spree::Variant.class_eval do
|
||||
|
||||
private
|
||||
|
||||
def update_weight_from_unit_value
|
||||
self.weight = unit_value / 1000 if self.product.variant_unit == 'weight' && unit_value.present?
|
||||
end
|
||||
|
||||
def update_units
|
||||
delete_unit_option_values
|
||||
|
||||
|
||||
@@ -155,4 +155,4 @@
|
||||
|
||||
.omega.four.columns
|
||||
= image_tag @object.promo_image.url if @object.promo_image.present?
|
||||
= f.file_field :pro_image
|
||||
= f.file_field :promo_image
|
||||
|
||||
@@ -1,10 +1,17 @@
|
||||
%td{:colspan => 3}
|
||||
.exchange-select-all-variants
|
||||
%label
|
||||
= check_box_tag 'order_cycle_outgoing_exchange_{{ $parent.$index }}_select_all_variants', 1, 1, 'ng-model' => 'exchange.select_all_variants', 'ng-click' => 'setExchangeVariants(exchange, incomingExchangesVariants(), exchange.select_all_variants)', 'id' => 'order_cycle_outgoing_exchange_{{ $parent.$index }}_select_all_variants'
|
||||
Select all
|
||||
|
||||
.exchange-product{'ng-repeat' => 'product in supplied_products | filter:productSuppliedToOrderCycle'}
|
||||
.exchange-product-details
|
||||
.supplier {{ product.supplier_name }}
|
||||
= check_box_tag 'order_cycle_outgoing_exchange_{{ $parent.$index }}_variants_{{ product.master_id }}', 1, 1, 'ng-hide' => 'product.variants', 'ng-model' => 'exchange.variants[product.master_id]', 'id' => 'order_cycle_outgoing_exchange_{{ $parent.$index }}_variants_{{ product.master_id }}'
|
||||
%img{'ng-src' => '{{ product.image_url }}'}
|
||||
{{ product.name }}
|
||||
%label
|
||||
= check_box_tag 'order_cycle_outgoing_exchange_{{ $parent.$index }}_variants_{{ product.master_id }}', 1, 1, 'ng-hide' => 'product.variants', 'ng-disabled' => 'product.variants.length > 0', 'ng-model' => 'exchange.variants[product.master_id]', 'id' => 'order_cycle_outgoing_exchange_{{ $parent.$index }}_variants_{{ product.master_id }}'
|
||||
%img{'ng-src' => '{{ product.image_url }}'}
|
||||
{{ product.name }}
|
||||
.exchange-product-variant{'ng-repeat' => 'variant in product.variants | filter:variantSuppliedToOrderCycle'}
|
||||
= check_box_tag 'order_cycle_outgoing_exchange_{{ $parent.$parent.$index }}_variants_{{ variant.id }}', 1, 1, 'ng-model' => 'exchange.variants[variant.id]', 'id' => 'order_cycle_outgoing_exchange_{{ $parent.$parent.$index }}_variants_{{ variant.id }}'
|
||||
{{ variant.label }}
|
||||
%label
|
||||
= check_box_tag 'order_cycle_outgoing_exchange_{{ $parent.$parent.$index }}_variants_{{ variant.id }}', 1, 1, 'ng-model' => 'exchange.variants[variant.id]', 'id' => 'order_cycle_outgoing_exchange_{{ $parent.$parent.$index }}_variants_{{ variant.id }}'
|
||||
{{ variant.label }}
|
||||
|
||||
@@ -1,18 +1,26 @@
|
||||
/ TODO: Unify this with exchange_distributed_products_form
|
||||
%td{:colspan => 3}
|
||||
.exchange-select-all-variants
|
||||
%label
|
||||
= check_box_tag 'order_cycle_incoming_exchange_{{ $parent.$index }}_select_all_variants', 1, 1, 'ng-model' => 'exchange.select_all_variants', 'ng-click' => 'setExchangeVariants(exchange, suppliedVariants(exchange.enterprise_id), exchange.select_all_variants)', 'id' => 'order_cycle_incoming_exchange_{{ $parent.$index }}_select_all_variants'
|
||||
Select all
|
||||
|
||||
.exchange-product{'ng-repeat' => 'product in enterprises[exchange.enterprise_id].supplied_products'}
|
||||
|
||||
.exchange-product-details
|
||||
= check_box_tag 'order_cycle_incoming_exchange_{{ $parent.$index }}_variants_{{ product.master_id }}', 1, 1, 'ng-hide' => 'product.variants', 'ng-model' => 'exchange.variants[product.master_id]', 'ofn-sync-distributions' => '{{ product.master_id }}', 'id' => 'order_cycle_incoming_exchange_{{ $parent.$index }}_variants_{{ product.master_id }}'
|
||||
%img{'ng-src' => '{{ product.image_url }}'}
|
||||
{{ product.name }}
|
||||
%label
|
||||
= check_box_tag 'order_cycle_incoming_exchange_{{ $parent.$index }}_variants_{{ product.master_id }}', 1, 1, 'ng-hide' => 'product.variants', 'ng-disabled' => 'product.variants.length > 0', 'ng-model' => 'exchange.variants[product.master_id]', 'ofn-sync-distributions' => '{{ product.master_id }}', 'id' => 'order_cycle_incoming_exchange_{{ $parent.$index }}_variants_{{ product.master_id }}'
|
||||
%img{'ng-src' => '{{ product.image_url }}'}
|
||||
{{ product.name }}
|
||||
|
||||
-# When the master variant is in the order cycle but the product has variants, we want to
|
||||
-# be able to remove the master variant, since it serves no purpose. Display a checkbox to do so.
|
||||
.exchange-product-variant{'ng-show' => 'exchange.variants[product.master_id] && product.variants'}
|
||||
= check_box_tag 'order_cycle_incoming_exchange_{{ $parent.$index }}_variants_{{ product.master_id }}', 1, 1, 'ng-model' => 'exchange.variants[product.master_id]', 'ofn-sync-distributions' => '{{ product.master_id }}', 'id' => 'order_cycle_incoming_exchange_{{ $parent.$index }}_variants_{{ product.master_id }}'
|
||||
Obsolete master
|
||||
%label
|
||||
= check_box_tag 'order_cycle_incoming_exchange_{{ $parent.$index }}_variants_{{ product.master_id }}', 1, 1, 'ng-model' => 'exchange.variants[product.master_id]', 'ofn-sync-distributions' => '{{ product.master_id }}', 'id' => 'order_cycle_incoming_exchange_{{ $parent.$index }}_variants_{{ product.master_id }}'
|
||||
Obsolete master
|
||||
|
||||
.exchange-product-variant{'ng-repeat' => 'variant in product.variants'}
|
||||
= check_box_tag 'order_cycle_incoming_exchange_{{ $parent.$parent.$index }}_variants_{{ variant.id }}', 1, 1, 'ng-model' => 'exchange.variants[variant.id]', 'ofn-sync-distributions' => '{{ variant.id }}', 'id' => 'order_cycle_incoming_exchange_{{ $parent.$parent.$index }}_variants_{{ variant.id }}'
|
||||
{{ variant.label }}
|
||||
%label
|
||||
= check_box_tag 'order_cycle_incoming_exchange_{{ $parent.$parent.$index }}_variants_{{ variant.id }}', 1, 1, 'ng-model' => 'exchange.variants[variant.id]', 'ofn-sync-distributions' => '{{ variant.id }}', 'id' => 'order_cycle_incoming_exchange_{{ $parent.$parent.$index }}_variants_{{ variant.id }}'
|
||||
{{ variant.label }}
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
%h2 Coordinator
|
||||
= f.label :coordinator_id, 'Coordinator'
|
||||
= f.collection_select :coordinator_id, coordinating_enterprises, :id, :name, {}, {'ng-model' => 'order_cycle.coordinator_id', 'ofn-on-change' => 'order_cycle.coordinator_fees = []', 'required' => true}
|
||||
= f.collection_select :coordinator_id, coordinating_enterprises, :id, :name, {include_blank: true}, {'ng-model' => 'order_cycle.coordinator_id', 'ofn-on-change' => 'order_cycle.coordinator_fees = []', 'required' => true}
|
||||
= render 'coordinator_fees', f: f
|
||||
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ r.element :order_cycle, @order_cycle do
|
||||
r.element :id
|
||||
end
|
||||
|
||||
r.list_of :exchanges do |exchange|
|
||||
r.list_of :exchanges, @order_cycle.exchanges.order('id ASC') do |exchange|
|
||||
r.element :id
|
||||
r.element :sender_id
|
||||
r.element :receiver_id
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
- if Rails.env.staging?
|
||||
- if Rails.env.staging? or Rails.env.production?
|
||||
:javascript
|
||||
(function (d, t) {
|
||||
var bh = d.createElement(t), s = d.getElementsByTagName(t)[0];
|
||||
@@ -7,11 +7,12 @@
|
||||
s.parentNode.insertBefore(bh, s);
|
||||
})(document, 'script');
|
||||
|
||||
- elsif Rails.env.production?
|
||||
:javascript
|
||||
(function (d, t) {
|
||||
var bh = d.createElement(t), s = d.getElementsByTagName(t)[0];
|
||||
bh.type = 'text/javascript';
|
||||
bh.src = '//www.bugherd.com/sidebarv2.js?apikey=xro3uv55objies58o2wrua';
|
||||
s.parentNode.insertBefore(bh, s);
|
||||
})(document, 'script');
|
||||
|
||||
-#- elsif Rails.env.production?
|
||||
-#:javascript
|
||||
-#(function (d, t) {
|
||||
-#var bh = d.createElement(t), s = d.getElementsByTagName(t)[0];
|
||||
-#bh.type = 'text/javascript';
|
||||
-#bh.src = '//www.bugherd.com/sidebarv2.js?apikey=xro3uv55objies58o2wrua';
|
||||
-#s.parentNode.insertBefore(bh, s);
|
||||
-#})(document, 'script');
|
||||
|
||||
@@ -22,6 +22,4 @@
|
||||
= yield
|
||||
|
||||
#footer
|
||||
|
||||
|
||||
= yield :scripts
|
||||
|
||||
20
app/views/shared/_account_sidebar.html.haml
Normal file
20
app/views/shared/_account_sidebar.html.haml
Normal file
@@ -0,0 +1,20 @@
|
||||
#account{"ng-controller" => "AccountSidebarCtrl"}
|
||||
.row
|
||||
.panel
|
||||
%p
|
||||
%strong= link_to "Manage my account", account_path
|
||||
- if enterprise_user?
|
||||
%strong= link_to "Enterprise admin", admin_path
|
||||
- if order = last_completed_order
|
||||
%dl
|
||||
%dt Current Hub:
|
||||
%dd= link_to current_distributor.name, main_app.shop_path
|
||||
%br
|
||||
%dt Last hub:
|
||||
%dd
|
||||
- if order.distributor != current_distributor
|
||||
= link_to "#{order.distributor.name}".html_safe, "",
|
||||
{class: distributor_link_class(order.distributor),
|
||||
"ng-click" => "emptyCart('#{main_app.shop_enterprise_path(order.distributor)}', $event)"}
|
||||
- else
|
||||
= order.distributor.name
|
||||
@@ -3,8 +3,10 @@
|
||||
active: "active()",
|
||||
select: "select()"}
|
||||
%form{"ng-submit" => "submit()"}
|
||||
.alert-box.alert{"ng-show" => "errors != null"}
|
||||
{{ errors }}
|
||||
.row
|
||||
.large-12.columns
|
||||
.alert-box.alert{"ng-show" => "errors != null"}
|
||||
{{ errors }}
|
||||
.row
|
||||
.large-12.columns
|
||||
%label{for: "email"} Email
|
||||
|
||||
@@ -1,9 +1,21 @@
|
||||
%nav.top-bar
|
||||
%section.top-bar-section
|
||||
%ul.left{"ng-controller" => "MenuCtrl"}
|
||||
%li
|
||||
%a.icon{"ng-click" => "toggle()"}
|
||||
%i.fi-list
|
||||
%li= link_to image_tag("ofn_logo_small.png"), root_path
|
||||
%li.divider
|
||||
- if spree_current_user.nil?
|
||||
= render 'shared/signed_out'
|
||||
- else
|
||||
= render 'shared/signed_in'
|
||||
|
||||
%section.top-bar-section
|
||||
%ul.right
|
||||
%li.cart
|
||||
%a.icon{href: cart_url}
|
||||
%i.fi-shopping-cart
|
||||
%span
|
||||
= cart_count
|
||||
items
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
%section#sidebar{ role: "complementary", "ng-controller" => "SidebarCtrl",
|
||||
"ng-class" => "{'active' : active()}"}
|
||||
%tabset
|
||||
= render partial: "shared/login_sidebar"
|
||||
= render partial: "shared/signup_sidebar"
|
||||
= render partial: "shared/forgot_sidebar"
|
||||
|
||||
- if spree_current_user.nil?
|
||||
%tabset
|
||||
= render partial: "shared/login_sidebar"
|
||||
= render partial: "shared/signup_sidebar"
|
||||
= render partial: "shared/forgot_sidebar"
|
||||
- else
|
||||
= render partial: "shared/account_sidebar"
|
||||
|
||||
= yield :sidebar
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
%li#login-link.hide= link_to "Login", "#sidebar", id: "sidebarLoginButton", class: "sidebar-button"
|
||||
%li#login-name= link_to "#{spree_current_user.email}", "#"
|
||||
%li#login-name
|
||||
%a.sidebar-button{"ng-click" => "toggle('/account')"}
|
||||
= spree_current_user.email
|
||||
%li.divider
|
||||
%li#sign-up-link.hide= link_to "Sign Up", "#"
|
||||
%li#sign-out-link= link_to "Sign Out", "/logout"
|
||||
%li#sign-out-link
|
||||
= link_to "Sign Out", "/logout"
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
%li#login-link
|
||||
%a.sidebar-button{"ng-click" => "toggleLogin()"} Login
|
||||
|
||||
%li#login-name.hide
|
||||
%a.sidebar-button{"ng-click" => "toggle('/login')"} Login
|
||||
%li.divider
|
||||
|
||||
%li#sign-up-link
|
||||
%a.sidebar-button{"ng-click" => "toggleSignup()"} Sign Up
|
||||
%a.sidebar-button{"ng-click" => "toggle('/signup')"} Sign Up
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
- for producer in current_producers
|
||||
.reveal-modal{id: "producer_details_#{producer.id}"}
|
||||
.reveal-modal{id: "producer_details_#{producer.id}", "data-reveal" => ""}
|
||||
.row
|
||||
- if producer.logo.exists?
|
||||
.large-1.columns
|
||||
@@ -17,10 +17,9 @@
|
||||
%a.close-reveal-modal ×
|
||||
|
||||
|
||||
|
||||
- for group in current_distributor.groups
|
||||
- for sibling in group.enterprises.except(current_distributor)
|
||||
.reveal-modal{id: "sibling_details_#{sibling.id}"}
|
||||
.reveal-modal{id: "sibling_details_#{sibling.id}", "data-reveal" => ""}
|
||||
.row
|
||||
- if sibling.logo.exists?
|
||||
.large-1.columns
|
||||
@@ -35,4 +34,3 @@
|
||||
.large-4.columns
|
||||
%img.about.right{src: sibling.promo_image.url(:large)}
|
||||
%a.close-reveal-modal ×
|
||||
|
||||
|
||||
@@ -24,12 +24,12 @@
|
||||
.large-6.columns
|
||||
= ba.text_field :lastname, "ng-model" => "order.bill_address.lastname"
|
||||
|
||||
%fieldset
|
||||
%fieldset#billing
|
||||
%legend Billing Address
|
||||
= f.fields_for :bill_address, @order.bill_address do |ba|
|
||||
.row
|
||||
.large-12.columns
|
||||
= ba.text_field :address1, label: "Billing Address",
|
||||
= ba.text_field :address1,
|
||||
"ng-model" => "order.bill_address.address1"
|
||||
.row
|
||||
.large-12.columns
|
||||
|
||||
@@ -6,5 +6,5 @@
|
||||
%ul
|
||||
- for sibling in group.enterprises.except(current_distributor)
|
||||
%li
|
||||
%a{"data-reveal-id" => "sibling_details_#{sibling.id}"}
|
||||
%a{"data-reveal-id" => "sibling_details_#{sibling.id}", "data-reveal" => ""}
|
||||
= sibling.name
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
%ul
|
||||
- for producer in current_producers
|
||||
%li
|
||||
%a{"data-reveal-id" => "producer_details_#{producer.id}"}
|
||||
%a{"data-reveal-id" => "producer_details_#{producer.id}", "data-reveal" => ""}
|
||||
= producer.name
|
||||
|
||||
@@ -12,6 +12,10 @@
|
||||
%th.quantity QTY
|
||||
%th.bulk Bulk
|
||||
%th.price.text-right Price
|
||||
%tbody{"ng-show" => "data.loading"}
|
||||
%tr
|
||||
%td{colspan: 6}
|
||||
%h3.text-center Loading Products
|
||||
%tbody{"ng-repeat" => "product in data.products | filter:query"}
|
||||
%tr{"class" => "product product-{{ product.id }}"}
|
||||
%td.name
|
||||
@@ -19,7 +23,7 @@
|
||||
%div
|
||||
%h5
|
||||
{{ product.name }}
|
||||
%a{"data-reveal-id" => "producer_details_{{product.supplier.id}}"}
|
||||
%a{"data-reveal-id" => "producer_details_{{product.supplier.id}}", "data-reveal" => ""}
|
||||
{{ product.supplier.name }}
|
||||
%td.notes {{ product.notes | truncate:80 }}
|
||||
%td
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
%shop.darkswarm
|
||||
- content_for :order_cycle_form do
|
||||
|
||||
%strong.avenir Ready for
|
||||
%select.avenir#order_cycle_id{"ng-model" => "order_cycle.order_cycle_id",
|
||||
"ng-change" => "changeOrderCycle()",
|
||||
"ng-options" => "oc.id as oc.time for oc in #{@order_cycles.map {|oc| {time: pickup_time(oc), id: oc.id}}.to_json}"}
|
||||
"ng-options" => "oc.id as oc.time for oc in #{@order_cycles.map {|oc| {time: pickup_time(oc), id: oc.id}}.to_json}",
|
||||
"popover-placement" => "bottom", "popover" => "testy", "popover-trigger" => "openTrigger"}
|
||||
|
||||
%closing
|
||||
-#%img{src: "/icon/goes/here"}
|
||||
%closing{"ng-if" => "OrderCycle.selected()"}
|
||||
Orders close
|
||||
%strong {{ OrderCycle.orders_close_at() | date_in_words }}
|
||||
|
||||
= render partial: "shop/details"
|
||||
|
||||
%products.row
|
||||
|
||||
@@ -23,6 +23,15 @@ Payment Details
|
||||
<%= @order.payments.first.andand.payment_method.andand.description.andand.html_safe %>
|
||||
|
||||
<% end %>
|
||||
|
||||
<%- if @order.shipping_method.andand.require_ship_address %>
|
||||
============================================================
|
||||
Shipping Details
|
||||
============================================================
|
||||
Your order will be shipped to:
|
||||
<%= @order.ship_address.to_s %>
|
||||
<% else %>
|
||||
|
||||
============================================================
|
||||
Collection / Delivery Details
|
||||
============================================================
|
||||
@@ -34,9 +43,11 @@ Collection / Delivery Details
|
||||
<% else %>
|
||||
<%= @order.distributor.next_collection_at %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
Thanks for your support.
|
||||
|
||||
|
||||
<%= @order.distributor.contact %>,
|
||||
<%= @order.distributor.name %>
|
||||
<%= @order.distributor.phone %>
|
||||
|
||||
@@ -41,18 +41,18 @@
|
||||
\:
|
||||
%span.order-total.grand-total= @order.display_total
|
||||
|
||||
.links{'data-hook' => "cart_buttons"}
|
||||
.row
|
||||
#empty-cart.columns.large-9{"data-hook" => ""}
|
||||
= form_tag empty_cart_path, :method => :put do
|
||||
#clear_cart_link{"data-hook" => ""}
|
||||
= link_to "Continue Shopping", main_app.shop_path, class: "button secondary"
|
||||
= t(:or)
|
||||
= submit_tag t(:empty_cart), :class => 'button secondary'
|
||||
.links{'data-hook' => "cart_buttons"}
|
||||
.row
|
||||
#empty-cart.columns.large-8{"data-hook" => ""}
|
||||
= form_tag empty_cart_path, :method => :put do
|
||||
#clear_cart_link{"data-hook" => ""}
|
||||
= link_to "Continue Shopping", main_app.shop_path, class: "button secondary"
|
||||
= t(:or)
|
||||
= submit_tag t(:empty_cart), :class => 'button secondary'
|
||||
|
||||
.columns.large-1
|
||||
= button_tag :class => 'secondary', :id => 'update-button' do
|
||||
= t(:update)
|
||||
.columns.large-2
|
||||
= link_to "Checkout", main_app.shop_checkout_path, class: "button checkout primary", id: "checkout-link"
|
||||
.columns.large-4.text-right
|
||||
= button_tag :class => 'secondary', :id => 'update-button' do
|
||||
= t(:update)
|
||||
= t(:or)
|
||||
= link_to "Checkout", main_app.shop_checkout_path, class: "button checkout primary", id: "checkout-link"
|
||||
|
||||
|
||||
13
app/views/spree/user_mailer/signup_confirmation.text.erb
Normal file
13
app/views/spree/user_mailer/signup_confirmation.text.erb
Normal file
@@ -0,0 +1,13 @@
|
||||
Hello,
|
||||
|
||||
Welcome to Australia's Open Food Network! Your login email is <%= @user.email %>
|
||||
|
||||
You can go online and start shopping through food hubs and local producers you like at vic.openfoodnetwork.org.au
|
||||
|
||||
We welcome all your questions and feedback; you can use the Send Feedback button on the site or email us at hello@openfoodnetwork.org
|
||||
|
||||
Thanks for getting on board and we look forward to introducing you to many more great farmers, food hubs and food!
|
||||
|
||||
Cheers,
|
||||
Kirsten Larsen and the OFN Team
|
||||
|
||||
8
app/views/spree/users/edit.html.haml
Normal file
8
app/views/spree/users/edit.html.haml
Normal file
@@ -0,0 +1,8 @@
|
||||
.darkswarm
|
||||
.row
|
||||
= render :partial => 'spree/shared/error_messages', :locals => { :target => @user }
|
||||
%h1= t(:editing_user)
|
||||
= form_for Spree::User.new, :as => @user, :url => spree.user_path(@user), :method => :put do |f|
|
||||
= render :partial => 'spree/shared/user_form', :locals => { :f => f }
|
||||
%p
|
||||
= f.submit t(:update), :class => 'button primary'
|
||||
33
app/views/spree/users/show.html.haml
Normal file
33
app/views/spree/users/show.html.haml
Normal file
@@ -0,0 +1,33 @@
|
||||
.darkswarm
|
||||
.row
|
||||
%h1= accurate_title
|
||||
.account-summary{"data-hook" => "account_summary"}
|
||||
%dl#user-info
|
||||
%dt= t(:email)
|
||||
%dd
|
||||
= @user.email
|
||||
(#{link_to t(:edit), spree.edit_account_path})
|
||||
.account-my-orders{"data-hook" => "account_my_orders"}
|
||||
%h3= t(:my_orders)
|
||||
- if @orders.present?
|
||||
%table.order-summary
|
||||
%thead
|
||||
%tr
|
||||
%th.order-number= t(:order_number)
|
||||
%th.order-date= t(:order_date)
|
||||
%th.order-status= t(:status)
|
||||
%th.order-payment-state= t(:payment_state)
|
||||
%th.order-shipment-state= t(:shipment_state)
|
||||
%th.order-total= t(:total)
|
||||
%tbody
|
||||
- @orders.each do |order|
|
||||
%tr{class: cycle('even', 'odd')}
|
||||
%td.order-number= link_to order.number, order_url(order)
|
||||
%td.order-date= l order.completed_at.to_date
|
||||
%td.order-status= t(order.state).titleize
|
||||
%td.order-payment-state= t("payment_states.#{order.payment_state}") if order.payment_state
|
||||
%td.order-shipment-state= t("shipment_states.#{order.shipment_state}") if order.shipment_state
|
||||
%td.order-total= money order.total
|
||||
- else
|
||||
%p= t(:you_have_no_orders_yet)
|
||||
%br/
|
||||
16
app/views/user_passwords/edit.html.haml
Normal file
16
app/views/user_passwords/edit.html.haml
Normal file
@@ -0,0 +1,16 @@
|
||||
= f_form_for @spree_user, :as => :spree_user, :url => spree.spree_user_password_path, :method => :put do |f|
|
||||
= render :partial => 'spree/shared/error_messages', :locals => { :target => @spree_user }
|
||||
%fieldset
|
||||
.row
|
||||
.small-12.medium-6.large-4.columns.medium-centered.large-centered
|
||||
%legend= t(:change_my_password)
|
||||
.row
|
||||
.small-12.medium-6.large-4.columns.medium-centered.large-centered
|
||||
= f.password_field :password
|
||||
.row
|
||||
.small-12.medium-6.large-4.columns.medium-centered.large-centered
|
||||
= f.password_field :password_confirmation
|
||||
= f.hidden_field :reset_password_token
|
||||
.row
|
||||
.small-10.medium-6.large-4.columns.small-centered
|
||||
= f.submit t(:update_password), :class => 'button primary'
|
||||
38
db/migrate/20140402032034_add_missing_indexes.rb
Normal file
38
db/migrate/20140402032034_add_missing_indexes.rb
Normal file
@@ -0,0 +1,38 @@
|
||||
class AddMissingIndexes < ActiveRecord::Migration
|
||||
def change
|
||||
add_index :adjustment_metadata, :enterprise_id
|
||||
|
||||
add_index :carts, :user_id
|
||||
|
||||
add_index :coordinator_fees, :order_cycle_id
|
||||
add_index :coordinator_fees, :enterprise_fee_id
|
||||
|
||||
add_index :distributors_payment_methods, :distributor_id
|
||||
add_index :distributors_payment_methods, :payment_method_id
|
||||
|
||||
add_index :enterprise_fees, :enterprise_id
|
||||
|
||||
add_index :enterprise_groups_enterprises, :enterprise_group_id
|
||||
add_index :enterprise_groups_enterprises, :enterprise_id
|
||||
|
||||
add_index :enterprise_roles, :user_id
|
||||
add_index :enterprise_roles, :enterprise_id
|
||||
|
||||
add_index :enterprises, :address_id
|
||||
|
||||
add_index :exchange_fees, :exchange_id
|
||||
add_index :exchange_fees, :enterprise_fee_id
|
||||
|
||||
add_index :exchange_variants, :exchange_id
|
||||
add_index :exchange_variants, :variant_id
|
||||
|
||||
add_index :exchanges, :order_cycle_id
|
||||
add_index :exchanges, :sender_id
|
||||
add_index :exchanges, :receiver_id
|
||||
add_index :exchanges, :payment_enterprise_id
|
||||
|
||||
add_index :product_distributions, :product_id
|
||||
add_index :product_distributions, :distributor_id
|
||||
add_index :product_distributions, :enterprise_fee_id
|
||||
end
|
||||
end
|
||||
36
db/schema.rb
36
db/schema.rb
@@ -11,7 +11,7 @@
|
||||
#
|
||||
# It's strongly recommended to check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(:version => 20140324025840) do
|
||||
ActiveRecord::Schema.define(:version => 20140402032034) do
|
||||
|
||||
create_table "adjustment_metadata", :force => true do |t|
|
||||
t.integer "adjustment_id"
|
||||
@@ -22,11 +22,14 @@ ActiveRecord::Schema.define(:version => 20140324025840) do
|
||||
end
|
||||
|
||||
add_index "adjustment_metadata", ["adjustment_id"], :name => "index_adjustment_metadata_on_adjustment_id"
|
||||
add_index "adjustment_metadata", ["enterprise_id"], :name => "index_adjustment_metadata_on_enterprise_id"
|
||||
|
||||
create_table "carts", :force => true do |t|
|
||||
t.integer "user_id"
|
||||
end
|
||||
|
||||
add_index "carts", ["user_id"], :name => "index_carts_on_user_id"
|
||||
|
||||
create_table "cms_blocks", :force => true do |t|
|
||||
t.integer "page_id", :null => false
|
||||
t.string "identifier", :null => false
|
||||
@@ -149,11 +152,17 @@ ActiveRecord::Schema.define(:version => 20140324025840) do
|
||||
t.integer "enterprise_fee_id"
|
||||
end
|
||||
|
||||
add_index "coordinator_fees", ["enterprise_fee_id"], :name => "index_coordinator_fees_on_enterprise_fee_id"
|
||||
add_index "coordinator_fees", ["order_cycle_id"], :name => "index_coordinator_fees_on_order_cycle_id"
|
||||
|
||||
create_table "distributors_payment_methods", :id => false, :force => true do |t|
|
||||
t.integer "distributor_id"
|
||||
t.integer "payment_method_id"
|
||||
end
|
||||
|
||||
add_index "distributors_payment_methods", ["distributor_id"], :name => "index_distributors_payment_methods_on_distributor_id"
|
||||
add_index "distributors_payment_methods", ["payment_method_id"], :name => "index_distributors_payment_methods_on_payment_method_id"
|
||||
|
||||
create_table "distributors_shipping_methods", :id => false, :force => true do |t|
|
||||
t.integer "distributor_id"
|
||||
t.integer "shipping_method_id"
|
||||
@@ -170,6 +179,8 @@ ActiveRecord::Schema.define(:version => 20140324025840) do
|
||||
t.datetime "updated_at", :null => false
|
||||
end
|
||||
|
||||
add_index "enterprise_fees", ["enterprise_id"], :name => "index_enterprise_fees_on_enterprise_id"
|
||||
|
||||
create_table "enterprise_groups", :force => true do |t|
|
||||
t.string "name"
|
||||
t.boolean "on_front_page"
|
||||
@@ -181,11 +192,17 @@ ActiveRecord::Schema.define(:version => 20140324025840) do
|
||||
t.integer "enterprise_id"
|
||||
end
|
||||
|
||||
add_index "enterprise_groups_enterprises", ["enterprise_group_id"], :name => "index_enterprise_groups_enterprises_on_enterprise_group_id"
|
||||
add_index "enterprise_groups_enterprises", ["enterprise_id"], :name => "index_enterprise_groups_enterprises_on_enterprise_id"
|
||||
|
||||
create_table "enterprise_roles", :force => true do |t|
|
||||
t.integer "user_id"
|
||||
t.integer "enterprise_id"
|
||||
end
|
||||
|
||||
add_index "enterprise_roles", ["enterprise_id"], :name => "index_enterprise_roles_on_enterprise_id"
|
||||
add_index "enterprise_roles", ["user_id"], :name => "index_enterprise_roles_on_user_id"
|
||||
|
||||
create_table "enterprises", :force => true do |t|
|
||||
t.string "name"
|
||||
t.string "description"
|
||||
@@ -215,6 +232,8 @@ ActiveRecord::Schema.define(:version => 20140324025840) do
|
||||
t.datetime "promo_image_updated_at"
|
||||
end
|
||||
|
||||
add_index "enterprises", ["address_id"], :name => "index_enterprises_on_address_id"
|
||||
|
||||
create_table "exchange_fees", :force => true do |t|
|
||||
t.integer "exchange_id"
|
||||
t.integer "enterprise_fee_id"
|
||||
@@ -222,6 +241,9 @@ ActiveRecord::Schema.define(:version => 20140324025840) do
|
||||
t.datetime "updated_at", :null => false
|
||||
end
|
||||
|
||||
add_index "exchange_fees", ["enterprise_fee_id"], :name => "index_exchange_fees_on_enterprise_fee_id"
|
||||
add_index "exchange_fees", ["exchange_id"], :name => "index_exchange_fees_on_exchange_id"
|
||||
|
||||
create_table "exchange_variants", :force => true do |t|
|
||||
t.integer "exchange_id"
|
||||
t.integer "variant_id"
|
||||
@@ -229,6 +251,9 @@ ActiveRecord::Schema.define(:version => 20140324025840) do
|
||||
t.datetime "updated_at", :null => false
|
||||
end
|
||||
|
||||
add_index "exchange_variants", ["exchange_id"], :name => "index_exchange_variants_on_exchange_id"
|
||||
add_index "exchange_variants", ["variant_id"], :name => "index_exchange_variants_on_variant_id"
|
||||
|
||||
create_table "exchanges", :force => true do |t|
|
||||
t.integer "order_cycle_id"
|
||||
t.integer "sender_id"
|
||||
@@ -241,6 +266,11 @@ ActiveRecord::Schema.define(:version => 20140324025840) do
|
||||
t.boolean "incoming", :default => false, :null => false
|
||||
end
|
||||
|
||||
add_index "exchanges", ["order_cycle_id"], :name => "index_exchanges_on_order_cycle_id"
|
||||
add_index "exchanges", ["payment_enterprise_id"], :name => "index_exchanges_on_payment_enterprise_id"
|
||||
add_index "exchanges", ["receiver_id"], :name => "index_exchanges_on_receiver_id"
|
||||
add_index "exchanges", ["sender_id"], :name => "index_exchanges_on_sender_id"
|
||||
|
||||
create_table "landing_page_images", :force => true do |t|
|
||||
t.datetime "created_at", :null => false
|
||||
t.datetime "updated_at", :null => false
|
||||
@@ -267,6 +297,10 @@ ActiveRecord::Schema.define(:version => 20140324025840) do
|
||||
t.integer "enterprise_fee_id"
|
||||
end
|
||||
|
||||
add_index "product_distributions", ["distributor_id"], :name => "index_product_distributions_on_distributor_id"
|
||||
add_index "product_distributions", ["enterprise_fee_id"], :name => "index_product_distributions_on_enterprise_fee_id"
|
||||
add_index "product_distributions", ["product_id"], :name => "index_product_distributions_on_product_id"
|
||||
|
||||
create_table "spree_activators", :force => true do |t|
|
||||
t.string "description"
|
||||
t.datetime "expires_at"
|
||||
|
||||
@@ -2,6 +2,7 @@ require 'spec_helper'
|
||||
require 'spree/api/testing_support/helpers'
|
||||
|
||||
describe UserPasswordsController do
|
||||
let(:user) { create(:user) }
|
||||
|
||||
before do
|
||||
@request.env["devise.mapping"] = Devise.mappings[:spree_user]
|
||||
@@ -15,11 +16,16 @@ describe UserPasswordsController do
|
||||
end
|
||||
|
||||
it "redirects to login when data is valid" do
|
||||
user = create(:user)
|
||||
spree_post :create, spree_user: { email: user.email}
|
||||
response.should be_redirect
|
||||
end
|
||||
|
||||
it "renders Darkswarm" do
|
||||
user.send_reset_password_instructions
|
||||
spree_get :edit, reset_password_token: user.reset_password_token
|
||||
response.should render_template "user_passwords/edit"
|
||||
end
|
||||
|
||||
describe "via ajax" do
|
||||
it "returns errors" do
|
||||
xhr :post, :create, spree_user: {}, use_route: :spree
|
||||
|
||||
@@ -141,9 +141,9 @@ feature %q{
|
||||
page.should have_selector 'td.distributors', text: 'My distributor'
|
||||
|
||||
# And it should have some fees
|
||||
OrderCycle.last.exchanges.first.enterprise_fees.should == [supplier_fee]
|
||||
OrderCycle.last.coordinator_fees.should == [coordinator_fee]
|
||||
OrderCycle.last.exchanges.last.enterprise_fees.should == [distributor_fee]
|
||||
OrderCycle.last.exchanges.incoming.first.enterprise_fees.should == [supplier_fee]
|
||||
OrderCycle.last.coordinator_fees.should == [coordinator_fee]
|
||||
OrderCycle.last.exchanges.outgoing.first.enterprise_fees.should == [distributor_fee]
|
||||
|
||||
# And it should have some variants selected
|
||||
OrderCycle.last.exchanges.first.variants.count.should == 2
|
||||
|
||||
@@ -58,7 +58,6 @@ feature "enterprises distributor info as rich text" do
|
||||
end
|
||||
|
||||
scenario "viewing distributor info with product distribution", js: true do
|
||||
ActionMailer::Base.deliveries.clear
|
||||
|
||||
d = create(:distributor_enterprise, distributor_info: 'Chu ge sai yubi dan <strong>bisento</strong> tobi ashi yubi ge omote.', next_collection_at: 'Thursday 2nd May')
|
||||
p = create(:product, :distributors => [d])
|
||||
@@ -67,6 +66,7 @@ feature "enterprises distributor info as rich text" do
|
||||
|
||||
login_to_consumer_section
|
||||
visit spree.select_distributor_order_path(d)
|
||||
ActionMailer::Base.deliveries.clear
|
||||
|
||||
# -- Product details page
|
||||
visit spree.product_path p
|
||||
@@ -110,6 +110,7 @@ feature "enterprises distributor info as rich text" do
|
||||
setup_shipping_details d
|
||||
|
||||
login_to_consumer_section
|
||||
ActionMailer::Base.deliveries.clear
|
||||
click_link 'Green Grass'
|
||||
visit enterprise_path d
|
||||
|
||||
@@ -146,7 +147,7 @@ feature "enterprises distributor info as rich text" do
|
||||
zone = create(:zone)
|
||||
c = Spree::Country.find_by_name('Australia')
|
||||
Spree::ZoneMember.create(:zoneable => c, :zone => zone)
|
||||
create(:shipping_method, zone: zone)
|
||||
create(:shipping_method, zone: zone, require_ship_address: false)
|
||||
create(:payment_method, :description => 'Cheque payment method', distributors: [distributor])
|
||||
end
|
||||
|
||||
|
||||
@@ -3,16 +3,16 @@ require 'spec_helper'
|
||||
feature "As a consumer I want to check out my cart", js: true do
|
||||
include AuthenticationWorkflow
|
||||
include WebHelper
|
||||
include ShopWorkflow
|
||||
|
||||
let(:distributor) { create(:distributor_enterprise) }
|
||||
let(:supplier) { create(:supplier_enterprise) }
|
||||
let(:order_cycle) { create(:order_cycle, distributors: [distributor], coordinator: create(:distributor_enterprise)) }
|
||||
let(:product) { create(:simple_product, supplier: supplier) }
|
||||
let(:order) { Spree::Order.last }
|
||||
|
||||
before do
|
||||
create_enterprise_group_for distributor
|
||||
exchange = Exchange.find(order_cycle.exchanges.to_enterprises(distributor).outgoing.first.id)
|
||||
exchange.variants << product.master
|
||||
end
|
||||
|
||||
describe "Login behaviour" do
|
||||
|
||||
@@ -3,17 +3,17 @@ require 'spec_helper'
|
||||
|
||||
feature "As a consumer I want to check out my cart", js: true do
|
||||
include AuthenticationWorkflow
|
||||
include ShopWorkflow
|
||||
include WebHelper
|
||||
|
||||
let(:distributor) { create(:distributor_enterprise) }
|
||||
let(:supplier) { create(:supplier_enterprise) }
|
||||
let(:order_cycle) { create(:order_cycle, distributors: [distributor], coordinator: create(:distributor_enterprise)) }
|
||||
let(:product) { create(:simple_product, supplier: supplier) }
|
||||
let(:order) { Spree::Order.last }
|
||||
|
||||
before do
|
||||
create_enterprise_group_for distributor
|
||||
exchange = Exchange.find(order_cycle.exchanges.to_enterprises(distributor).outgoing.first.id)
|
||||
exchange.variants << product.master
|
||||
end
|
||||
describe "Attempting to access checkout without meeting the preconditions" do
|
||||
it "redirects to the homepage if no distributor is selected" do
|
||||
|
||||
@@ -3,19 +3,20 @@ require 'spec_helper'
|
||||
|
||||
feature "As a consumer I want to check out my cart", js: true do
|
||||
include AuthenticationWorkflow
|
||||
include ShopWorkflow
|
||||
include WebHelper
|
||||
|
||||
let(:distributor) { create(:distributor_enterprise) }
|
||||
let(:supplier) { create(:supplier_enterprise) }
|
||||
let(:order_cycle) { create(:order_cycle, distributors: [distributor], coordinator: create(:distributor_enterprise)) }
|
||||
let(:product) { create(:simple_product, supplier: supplier) }
|
||||
let(:order) { Spree::Order.last }
|
||||
|
||||
before do
|
||||
create_enterprise_group_for distributor
|
||||
exchange = Exchange.find(order_cycle.exchanges.to_enterprises(distributor).outgoing.first.id)
|
||||
exchange.variants << product.master
|
||||
end
|
||||
|
||||
# Disabled :in for performance reasons
|
||||
[:out].each do |auth_state|
|
||||
describe "logged #{auth_state.to_s}, distributor selected, order cycle selected, product in cart" do
|
||||
let(:user) { create_enterprise_user }
|
||||
@@ -36,12 +37,9 @@ feature "As a consumer I want to check out my cart", js: true do
|
||||
distributor.shipping_methods << sm2
|
||||
visit "/shop/checkout"
|
||||
end
|
||||
it "shows all shipping methods" do
|
||||
it "shows all shipping methods, but doesn't show ship address when not needed" do
|
||||
page.should have_content "Frogs"
|
||||
page.should have_content "Donkeys"
|
||||
end
|
||||
|
||||
it "doesn't show ship address forms when a shipping method wants no address" do
|
||||
choose(sm2.name)
|
||||
find("#ship_address", visible: false).visible?.should be_false
|
||||
end
|
||||
@@ -74,7 +72,9 @@ feature "As a consumer I want to check out my cart", js: true do
|
||||
it "copies billing address to hidden shipping address fields" do
|
||||
choose(sm1.name)
|
||||
check "Shipping address same as billing address?"
|
||||
fill_in "Billing Address", with: "testy"
|
||||
within "#billing" do
|
||||
fill_in "Address", with: "testy"
|
||||
end
|
||||
within "#ship_address_hidden" do
|
||||
find("#order_ship_address_attributes_address1", visible: false).value.should == "testy"
|
||||
end
|
||||
@@ -112,7 +112,7 @@ feature "As a consumer I want to check out my cart", js: true do
|
||||
within "#details" do
|
||||
fill_in "First Name", with: "Will"
|
||||
fill_in "Last Name", with: "Marshall"
|
||||
fill_in "Billing Address", with: "123 Your Face"
|
||||
fill_in "Address", with: "123 Your Face"
|
||||
select "Australia", from: "Country"
|
||||
select "Victoria", from: "State"
|
||||
fill_in "Customer E-Mail", with: "test@test.com"
|
||||
@@ -130,7 +130,7 @@ feature "As a consumer I want to check out my cart", js: true do
|
||||
within "#details" do
|
||||
fill_in "First Name", with: "Will"
|
||||
fill_in "Last Name", with: "Marshall"
|
||||
fill_in "Billing Address", with: "123 Your Face"
|
||||
fill_in "Address", with: "123 Your Face"
|
||||
select "Australia", from: "Country"
|
||||
select "Victoria", from: "State"
|
||||
fill_in "Customer E-Mail", with: "test@test.com"
|
||||
@@ -149,19 +149,3 @@ feature "As a consumer I want to check out my cart", js: true do
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
def select_distributor
|
||||
visit "/"
|
||||
click_link distributor.name
|
||||
end
|
||||
|
||||
def select_order_cycle
|
||||
exchange = Exchange.find(order_cycle.exchanges.to_enterprises(distributor).outgoing.first.id)
|
||||
visit "/shop"
|
||||
select exchange.pickup_time, from: "order_cycle_id"
|
||||
end
|
||||
|
||||
def add_product_to_cart
|
||||
fill_in "variants[#{product.master.id}]", with: product.master.on_hand - 1
|
||||
first("form.custom > input.button.right").click
|
||||
end
|
||||
|
||||
@@ -13,13 +13,10 @@ feature "As a consumer I want to shop with a distributor", js: true do
|
||||
click_link distributor.name
|
||||
end
|
||||
|
||||
it "shows a distributor" do
|
||||
it "shows a distributor with images" do
|
||||
visit shop_path
|
||||
page.should have_text distributor.name
|
||||
end
|
||||
|
||||
it "shows distributor images" do
|
||||
visit shop_path
|
||||
find("#tab_about a").click
|
||||
first("distributor img")['src'].should == distributor.logo.url(:thumb)
|
||||
first("#about img")['src'].should == distributor.promo_image.url(:large)
|
||||
@@ -43,32 +40,27 @@ feature "As a consumer I want to shop with a distributor", js: true do
|
||||
end
|
||||
|
||||
describe "selecting an order cycle" do
|
||||
let(:oc1) {create(:simple_order_cycle, distributors: [distributor], orders_close_at: 2.days.from_now)}
|
||||
let(:oc2) {create(:simple_order_cycle, distributors: [distributor], orders_close_at: 3.days.from_now)}
|
||||
let(:exchange1) { Exchange.find(oc1.exchanges.to_enterprises(distributor).outgoing.first.id) }
|
||||
let(:exchange2) { Exchange.find(oc2.exchanges.to_enterprises(distributor).outgoing.first.id) }
|
||||
it "selects an order cycle if only one is open" do
|
||||
# create order cycle
|
||||
oc1 = create(:simple_order_cycle, distributors: [distributor])
|
||||
exchange = Exchange.find(oc1.exchanges.to_enterprises(distributor).outgoing.first.id)
|
||||
exchange.update_attribute :pickup_time, "turtles"
|
||||
exchange1.update_attribute :pickup_time, "turtles"
|
||||
visit shop_path
|
||||
page.should have_selector "option[selected]", text: 'turtles'
|
||||
end
|
||||
|
||||
describe "with multiple order cycles" do
|
||||
let(:oc1) {create(:simple_order_cycle, distributors: [distributor], orders_close_at: 2.days.from_now)}
|
||||
let(:oc2) {create(:simple_order_cycle, distributors: [distributor], orders_close_at: 3.days.from_now)}
|
||||
before do
|
||||
exchange = Exchange.find(oc1.exchanges.to_enterprises(distributor).outgoing.first.id)
|
||||
exchange.update_attribute :pickup_time, "frogs"
|
||||
exchange = Exchange.find(oc2.exchanges.to_enterprises(distributor).outgoing.first.id)
|
||||
exchange.update_attribute :pickup_time, "turtles"
|
||||
exchange1.update_attribute :pickup_time, "frogs"
|
||||
exchange2.update_attribute :pickup_time, "turtles"
|
||||
visit shop_path
|
||||
end
|
||||
|
||||
it "shows a select with all order cycles" do
|
||||
it "shows a select with all order cycles, but doesn't show the products by default" do
|
||||
page.should have_selector "option", text: 'frogs'
|
||||
page.should have_selector "option", text: 'turtles'
|
||||
end
|
||||
|
||||
it "doesn't show the table before an order cycle is selected" do
|
||||
page.should_not have_selector("input.button.right", visible: true)
|
||||
end
|
||||
|
||||
@@ -80,33 +72,20 @@ feature "As a consumer I want to shop with a distributor", js: true do
|
||||
describe "with products in our order cycle" do
|
||||
let(:product) { create(:simple_product) }
|
||||
before do
|
||||
exchange = Exchange.find(oc1.exchanges.to_enterprises(distributor).outgoing.first.id)
|
||||
exchange.variants << product.master
|
||||
exchange1.variants << product.master
|
||||
visit shop_path
|
||||
end
|
||||
|
||||
it "allows us to select an order cycle" do
|
||||
select "frogs", :from => "order_cycle_id"
|
||||
it "allows us to select an order cycle, thus showing products" do
|
||||
page.should_not have_content product.name
|
||||
Spree::Order.last.order_cycle.should == nil
|
||||
|
||||
select "frogs", :from => "order_cycle_id"
|
||||
page.should have_selector "products"
|
||||
page.should have_content "Orders close 2 days from now"
|
||||
Spree::Order.last.order_cycle.should == oc1
|
||||
end
|
||||
|
||||
it "doesn't show products before an order cycle is selected" do
|
||||
page.should_not have_content product.name
|
||||
end
|
||||
|
||||
it "shows products when an order cycle has been selected" do
|
||||
select "frogs", :from => "order_cycle_id"
|
||||
page.should have_content product.name
|
||||
end
|
||||
|
||||
it "updates the orders close note when order cycle is changed" do
|
||||
oc1.stub(:orders_close_at).and_return 3.days.from_now
|
||||
select "turtles", :from => "order_cycle_id"
|
||||
page.should have_content "Orders close 3 days from now"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -164,13 +143,14 @@ feature "As a consumer I want to shop with a distributor", js: true do
|
||||
end
|
||||
end
|
||||
|
||||
describe "filtering on hand and on demand products" do
|
||||
describe "filtering products" do
|
||||
let(:oc) { create(:simple_order_cycle, distributors: [distributor]) }
|
||||
let(:p1) { create(:simple_product, on_demand: false) }
|
||||
let(:p2) { create(:simple_product, on_demand: true) }
|
||||
let(:p3) { create(:simple_product, on_demand: false) }
|
||||
let(:p4) { create(:simple_product, on_demand: false) }
|
||||
let(:p5) { create(:simple_product, on_demand: false) }
|
||||
let(:p6) { create(:simple_product, on_demand: false) }
|
||||
let(:v1) { create(:variant, product: p4, unit_value: 2) }
|
||||
let(:v2) { create(:variant, product: p4, unit_value: 3, on_demand: false) }
|
||||
let(:v3) { create(:variant, product: p4, unit_value: 4, on_demand: true) }
|
||||
@@ -183,6 +163,8 @@ feature "As a consumer I want to shop with a distributor", js: true do
|
||||
p1.master.update_attribute(:count_on_hand, 1)
|
||||
p2.master.update_attribute(:count_on_hand, 0)
|
||||
p3.master.update_attribute(:count_on_hand, 0)
|
||||
p6.master.update_attribute(:count_on_hand, 1)
|
||||
p6.delete
|
||||
v1.update_attribute(:count_on_hand, 1)
|
||||
v2.update_attribute(:count_on_hand, 0)
|
||||
v3.update_attribute(:count_on_hand, 0)
|
||||
@@ -193,6 +175,7 @@ feature "As a consumer I want to shop with a distributor", js: true do
|
||||
exchange.variants << p1.master
|
||||
exchange.variants << p2.master
|
||||
exchange.variants << p3.master
|
||||
exchange.variants << p6.master
|
||||
exchange.variants << v1
|
||||
exchange.variants << v2
|
||||
exchange.variants << v3
|
||||
@@ -224,6 +207,9 @@ feature "As a consumer I want to shop with a distributor", js: true do
|
||||
|
||||
# It does not show products that have no available variants in this distribution
|
||||
page.should_not have_content p5.name
|
||||
|
||||
# It does not show deleted products
|
||||
page.should_not have_content p6.name
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
16
spec/javascripts/unit/darkswarm/navigation.js.coffee
Normal file
16
spec/javascripts/unit/darkswarm/navigation.js.coffee
Normal file
@@ -0,0 +1,16 @@
|
||||
describe 'Navigation service', ->
|
||||
Navigation = null
|
||||
|
||||
beforeEach ->
|
||||
module 'Darkswarm'
|
||||
inject ($injector)->
|
||||
Navigation = $injector.get("Navigation")
|
||||
|
||||
it "caches the path provided", ->
|
||||
Navigation.navigate "/foo"
|
||||
expect(Navigation.path).toEqual "/foo"
|
||||
|
||||
it "defaults to the first path in the list", ->
|
||||
Navigation.paths = ["/test", "/bar"]
|
||||
Navigation.navigate()
|
||||
expect(Navigation.path).toEqual "/test"
|
||||
@@ -19,6 +19,7 @@ describe 'OrderCycle controllers', ->
|
||||
variantSuppliedToOrderCycle: jasmine.createSpy('variantSuppliedToOrderCycle').andReturn('variant supplied')
|
||||
exchangeDirection: jasmine.createSpy('exchangeDirection').andReturn('exchange direction')
|
||||
toggleProducts: jasmine.createSpy('toggleProducts')
|
||||
setExchangeVariants: jasmine.createSpy('setExchangeVariants')
|
||||
addSupplier: jasmine.createSpy('addSupplier')
|
||||
addDistributor: jasmine.createSpy('addDistributor')
|
||||
removeExchange: jasmine.createSpy('removeExchange')
|
||||
@@ -31,6 +32,7 @@ describe 'OrderCycle controllers', ->
|
||||
Enterprise =
|
||||
index: jasmine.createSpy('index').andReturn('enterprises list')
|
||||
supplied_products: 'supplied products'
|
||||
suppliedVariants: jasmine.createSpy('suppliedVariants').andReturn('supplied variants')
|
||||
totalVariants: jasmine.createSpy('totalVariants').andReturn('variants total')
|
||||
EnterpriseFee =
|
||||
index: jasmine.createSpy('index').andReturn('enterprise fees list')
|
||||
@@ -63,10 +65,18 @@ describe 'OrderCycle controllers', ->
|
||||
EnterpriseFee.loaded = false
|
||||
expect(scope.loaded()).toBe(false)
|
||||
|
||||
it "delegates suppliedVariants to Enterprise", ->
|
||||
expect(scope.suppliedVariants('enterprise_id')).toEqual('supplied variants')
|
||||
expect(Enterprise.suppliedVariants).toHaveBeenCalledWith('enterprise_id')
|
||||
|
||||
it 'Delegates exchangeSelectedVariants to OrderCycle', ->
|
||||
expect(scope.exchangeSelectedVariants('exchange')).toEqual('variants selected')
|
||||
expect(OrderCycle.exchangeSelectedVariants).toHaveBeenCalledWith('exchange')
|
||||
|
||||
it "delegates setExchangeVariants to OrderCycle", ->
|
||||
scope.setExchangeVariants('exchange', 'variants', 'selected')
|
||||
expect(OrderCycle.setExchangeVariants).toHaveBeenCalledWith('exchange', 'variants', 'selected')
|
||||
|
||||
it 'Delegates enterpriseTotalVariants to Enterprise', ->
|
||||
expect(scope.enterpriseTotalVariants('enterprise')).toEqual('variants total')
|
||||
expect(Enterprise.totalVariants).toHaveBeenCalledWith('enterprise')
|
||||
@@ -169,6 +179,7 @@ describe 'OrderCycle controllers', ->
|
||||
variantSuppliedToOrderCycle: jasmine.createSpy('variantSuppliedToOrderCycle').andReturn('variant supplied')
|
||||
exchangeDirection: jasmine.createSpy('exchangeDirection').andReturn('exchange direction')
|
||||
toggleProducts: jasmine.createSpy('toggleProducts')
|
||||
setExchangeVariants: jasmine.createSpy('setExchangeVariants')
|
||||
addSupplier: jasmine.createSpy('addSupplier')
|
||||
addDistributor: jasmine.createSpy('addDistributor')
|
||||
removeExchange: jasmine.createSpy('removeExchange')
|
||||
@@ -181,6 +192,7 @@ describe 'OrderCycle controllers', ->
|
||||
Enterprise =
|
||||
index: jasmine.createSpy('index').andReturn('enterprises list')
|
||||
supplied_products: 'supplied products'
|
||||
suppliedVariants: jasmine.createSpy('suppliedVariants').andReturn('supplied variants')
|
||||
totalVariants: jasmine.createSpy('totalVariants').andReturn('variants total')
|
||||
EnterpriseFee =
|
||||
index: jasmine.createSpy('index').andReturn('enterprise fees list')
|
||||
@@ -213,10 +225,18 @@ describe 'OrderCycle controllers', ->
|
||||
OrderCycle.loaded = false
|
||||
expect(scope.loaded()).toBe(false)
|
||||
|
||||
it "delegates suppliedVariants to Enterprise", ->
|
||||
expect(scope.suppliedVariants('enterprise_id')).toEqual('supplied variants')
|
||||
expect(Enterprise.suppliedVariants).toHaveBeenCalledWith('enterprise_id')
|
||||
|
||||
it 'Delegates exchangeSelectedVariants to OrderCycle', ->
|
||||
expect(scope.exchangeSelectedVariants('exchange')).toEqual('variants selected')
|
||||
expect(OrderCycle.exchangeSelectedVariants).toHaveBeenCalledWith('exchange')
|
||||
|
||||
it "delegates setExchangeVariants to OrderCycle", ->
|
||||
scope.setExchangeVariants('exchange', 'variants', 'selected')
|
||||
expect(OrderCycle.setExchangeVariants).toHaveBeenCalledWith('exchange', 'variants', 'selected')
|
||||
|
||||
it 'Delegates totalVariants to Enterprise', ->
|
||||
expect(scope.enterpriseTotalVariants('enterprise')).toEqual('variants total')
|
||||
expect(Enterprise.totalVariants).toHaveBeenCalledWith('enterprise')
|
||||
@@ -332,6 +352,25 @@ describe 'OrderCycle services', ->
|
||||
$httpBackend.flush()
|
||||
expect(Enterprise.supplied_products).toEqual [1, 2, 3, 4, 5, 6]
|
||||
|
||||
it "finds supplied variants for an enterprise", ->
|
||||
spyOn(Enterprise, 'variantsOf').andReturn(10)
|
||||
Enterprise.index()
|
||||
$httpBackend.flush()
|
||||
expect(Enterprise.suppliedVariants(1)).toEqual [10, 10]
|
||||
|
||||
describe "finding the variants of a product", ->
|
||||
it "returns the master for products without variants", ->
|
||||
p =
|
||||
master_id: 1
|
||||
variants: []
|
||||
expect(Enterprise.variantsOf(p)).toEqual [1]
|
||||
|
||||
it "returns the variant ids for products with variants", ->
|
||||
p =
|
||||
master_id: 1
|
||||
variants: [{id: 2}, {id: 3}]
|
||||
expect(Enterprise.variantsOf(p)).toEqual [2, 3]
|
||||
|
||||
it 'counts total variants supplied by an enterprise', ->
|
||||
enterprise =
|
||||
supplied_products: [
|
||||
@@ -450,6 +489,12 @@ describe 'OrderCycle services', ->
|
||||
OrderCycle.toggleProducts(exchange)
|
||||
expect(exchange.showProducts).toEqual(true)
|
||||
|
||||
describe "setting exchange variants", ->
|
||||
it "sets all variants to the provided value", ->
|
||||
exchange = {variants: {2: false}}
|
||||
OrderCycle.setExchangeVariants(exchange, [1, 2, 3], true)
|
||||
expect(exchange.variants).toEqual {1: true, 2: true, 3: true}
|
||||
|
||||
describe 'adding suppliers', ->
|
||||
exchange = null
|
||||
|
||||
@@ -725,35 +770,62 @@ describe 'OrderCycle services', ->
|
||||
]
|
||||
|
||||
it 'converts coordinator fees into a list of ids', ->
|
||||
data =
|
||||
order_cycle =
|
||||
coordinator_fees: [
|
||||
{id: 1}
|
||||
{id: 2}
|
||||
]
|
||||
|
||||
data = OrderCycle.translateCoordinatorFees(data)
|
||||
data = OrderCycle.translateCoordinatorFees(order_cycle)
|
||||
|
||||
expect(data.coordinator_fees).toBeUndefined()
|
||||
expect(data.coordinator_fee_ids).toEqual [1, 2]
|
||||
|
||||
it 'converts exchange fees into a list of ids', ->
|
||||
data =
|
||||
incoming_exchanges: [
|
||||
enterprise_fees: [
|
||||
{id: 1}
|
||||
{id: 2}
|
||||
it "preserves original data when converting coordinator fees", ->
|
||||
OrderCycle.order_cycle =
|
||||
coordinator_fees: [
|
||||
{id: 1}
|
||||
{id: 2}
|
||||
]
|
||||
]
|
||||
outgoing_exchanges: [
|
||||
enterprise_fees: [
|
||||
{id: 3}
|
||||
{id: 4}
|
||||
|
||||
data = OrderCycle.deepCopy()
|
||||
data = OrderCycle.translateCoordinatorFees(data)
|
||||
|
||||
expect(OrderCycle.order_cycle.coordinator_fees).toEqual [{id: 1}, {id: 2}]
|
||||
expect(OrderCycle.order_cycle.coordinator_fee_ids).toBeUndefined()
|
||||
|
||||
describe "converting exchange fees into a list of ids", ->
|
||||
order_cycle = null
|
||||
data = null
|
||||
|
||||
beforeEach ->
|
||||
order_cycle =
|
||||
incoming_exchanges: [
|
||||
enterprise_fees: [
|
||||
{id: 1}
|
||||
{id: 2}
|
||||
]
|
||||
]
|
||||
]
|
||||
outgoing_exchanges: [
|
||||
enterprise_fees: [
|
||||
{id: 3}
|
||||
{id: 4}
|
||||
]
|
||||
]
|
||||
OrderCycle.order_cycle = order_cycle
|
||||
|
||||
data = OrderCycle.translateExchangeFees(data)
|
||||
data = OrderCycle.deepCopy()
|
||||
data = OrderCycle.translateExchangeFees(data)
|
||||
|
||||
expect(data.incoming_exchanges[0].enterprise_fees).toBeUndefined()
|
||||
expect(data.outgoing_exchanges[0].enterprise_fees).toBeUndefined()
|
||||
expect(data.incoming_exchanges[0].enterprise_fee_ids).toEqual [1, 2]
|
||||
expect(data.outgoing_exchanges[0].enterprise_fee_ids).toEqual [3, 4]
|
||||
it 'converts exchange fees into a list of ids', ->
|
||||
expect(data.incoming_exchanges[0].enterprise_fees).toBeUndefined()
|
||||
expect(data.outgoing_exchanges[0].enterprise_fees).toBeUndefined()
|
||||
expect(data.incoming_exchanges[0].enterprise_fee_ids).toEqual [1, 2]
|
||||
expect(data.outgoing_exchanges[0].enterprise_fee_ids).toEqual [3, 4]
|
||||
|
||||
it "preserves original data when converting exchange fees", ->
|
||||
expect(order_cycle.incoming_exchanges[0].enterprise_fees).toEqual [{id: 1}, {id: 2}]
|
||||
expect(order_cycle.outgoing_exchanges[0].enterprise_fees).toEqual [{id: 3}, {id: 4}]
|
||||
expect(order_cycle.incoming_exchanges[0].enterprise_fee_ids).toBeUndefined()
|
||||
expect(order_cycle.outgoing_exchanges[0].enterprise_fee_ids).toBeUndefined()
|
||||
|
||||
@@ -17,6 +17,7 @@ describe Spree::OrderMailer do
|
||||
product_distribution = create(:product_distribution, :product => product, :distributor => @distributor)
|
||||
@shipping_instructions = "pick up on thursday please!"
|
||||
@order1 = create(:order, :distributor => @distributor, :bill_address => @bill_address, :special_instructions => @shipping_instructions)
|
||||
ActionMailer::Base.deliveries = []
|
||||
end
|
||||
|
||||
it "should send an email when given an order" do
|
||||
|
||||
20
spec/mailers/user_mailer_spec.rb
Normal file
20
spec/mailers/user_mailer_spec.rb
Normal file
@@ -0,0 +1,20 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe Spree::UserMailer do
|
||||
let(:user) { build(:user) }
|
||||
|
||||
after do
|
||||
ActionMailer::Base.deliveries.clear
|
||||
end
|
||||
|
||||
before do
|
||||
ActionMailer::Base.delivery_method = :test
|
||||
ActionMailer::Base.perform_deliveries = true
|
||||
ActionMailer::Base.deliveries = []
|
||||
end
|
||||
|
||||
it "sends an email when given a user" do
|
||||
Spree::UserMailer.signup_confirmation(user).deliver
|
||||
ActionMailer::Base.deliveries.count.should == 1
|
||||
end
|
||||
end
|
||||
@@ -13,13 +13,17 @@ describe Exchange do
|
||||
end
|
||||
end
|
||||
|
||||
it "should not be valid when sender and receiver pair are not unique for its order cycle" do
|
||||
it "should not be valid when (sender, receiver, direction) set are not unique for its order cycle" do
|
||||
e1 = create(:exchange)
|
||||
|
||||
e2 = build(:exchange,
|
||||
:order_cycle => e1.order_cycle, :sender => e1.sender, :receiver => e1.receiver)
|
||||
:order_cycle => e1.order_cycle, :sender => e1.sender, :receiver => e1.receiver, :incoming => e1.incoming)
|
||||
e2.should_not be_valid
|
||||
|
||||
e2.incoming = !e2.incoming
|
||||
e2.should be_valid
|
||||
e2.incoming = !e2.incoming
|
||||
|
||||
e2.receiver = create(:enterprise)
|
||||
e2.should be_valid
|
||||
|
||||
|
||||
@@ -181,14 +181,19 @@ describe Spree::Order do
|
||||
end
|
||||
|
||||
describe "setting the order cycle" do
|
||||
let(:oc) { create(:simple_order_cycle) }
|
||||
|
||||
it "empties the cart when changing the order cycle" do
|
||||
subject.should_receive(:empty!)
|
||||
subject.set_order_cycle! oc
|
||||
end
|
||||
|
||||
it "sets the order cycle when no distributor is set" do
|
||||
oc = create(:simple_order_cycle)
|
||||
subject.set_order_cycle! oc
|
||||
subject.order_cycle.should == oc
|
||||
end
|
||||
|
||||
it "keeps the distributor when it is available in the new order cycle" do
|
||||
oc = create(:simple_order_cycle)
|
||||
d = create(:distributor_enterprise)
|
||||
create(:exchange, order_cycle: oc, sender: oc.coordinator, receiver: d, incoming: false)
|
||||
|
||||
@@ -200,7 +205,6 @@ describe Spree::Order do
|
||||
end
|
||||
|
||||
it "clears the distributor if it is not available at that order cycle" do
|
||||
oc = create(:simple_order_cycle)
|
||||
d = create(:distributor_enterprise)
|
||||
|
||||
subject.distributor = d
|
||||
@@ -211,7 +215,6 @@ describe Spree::Order do
|
||||
end
|
||||
|
||||
it "clears the order cycle when setting to nil" do
|
||||
oc = create(:simple_order_cycle)
|
||||
d = create(:distributor_enterprise)
|
||||
subject.set_order_cycle! oc
|
||||
subject.distributor = d
|
||||
|
||||
9
spec/models/spree/user_spec.rb
Normal file
9
spec/models/spree/user_spec.rb
Normal file
@@ -0,0 +1,9 @@
|
||||
describe Spree.user_class do
|
||||
context "#create" do
|
||||
|
||||
it "should send a signup email" do
|
||||
Spree::UserMailer.should_receive(:signup_confirmation).and_return(double(:deliver => true))
|
||||
create(:user)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -115,6 +115,41 @@ module Spree
|
||||
end
|
||||
|
||||
describe "unit value/description" do
|
||||
describe "setting the variant's weight from the unit value" do
|
||||
it "sets the variant's weight when unit is weight" do
|
||||
p = create(:simple_product, variant_unit: nil, variant_unit_scale: nil)
|
||||
v = create(:variant, product: p, weight: nil)
|
||||
|
||||
p.update_attributes! variant_unit: 'weight', variant_unit_scale: 1
|
||||
v.update_attributes! unit_value: 10, unit_description: 'foo'
|
||||
|
||||
v.reload.weight.should == 0.01
|
||||
end
|
||||
|
||||
it "does nothing when unit is not weight" do
|
||||
p = create(:simple_product, variant_unit: nil, variant_unit_scale: nil)
|
||||
v = create(:variant, product: p, weight: 123)
|
||||
|
||||
p.update_attributes! variant_unit: 'volume', variant_unit_scale: 1
|
||||
v.update_attributes! unit_value: 10, unit_description: 'foo'
|
||||
|
||||
v.reload.weight.should == 123
|
||||
end
|
||||
|
||||
it "does nothing when unit_value is not set" do
|
||||
p = create(:simple_product, variant_unit: nil, variant_unit_scale: nil)
|
||||
v = create(:variant, product: p, weight: 123)
|
||||
|
||||
p.update_attributes! variant_unit: 'weight', variant_unit_scale: 1
|
||||
|
||||
# Although invalid, this calls the before_validation callback, which would
|
||||
# error if not handling unit_value == nil case
|
||||
v.update_attributes(unit_value: nil, unit_description: 'foo').should be_false
|
||||
|
||||
v.reload.weight.should == 123
|
||||
end
|
||||
end
|
||||
|
||||
context "when the variant initially has no value" do
|
||||
context "when the required option value does not exist" do
|
||||
let!(:p) { create(:simple_product, variant_unit: nil, variant_unit_scale: nil) }
|
||||
|
||||
19
spec/support/request/shop_workflow.rb
Normal file
19
spec/support/request/shop_workflow.rb
Normal file
@@ -0,0 +1,19 @@
|
||||
module ShopWorkflow
|
||||
def select_distributor
|
||||
# If no order cycles are available this is much faster
|
||||
visit "/"
|
||||
click_link distributor.name
|
||||
end
|
||||
|
||||
# These methods are naughty and write to the DB directly
|
||||
# Because loading the whole Angular app is slow
|
||||
def select_order_cycle
|
||||
exchange = Exchange.find(order_cycle.exchanges.to_enterprises(distributor).outgoing.first.id)
|
||||
exchange.variants << product.master
|
||||
order.update_attribute :order_cycle, order_cycle
|
||||
end
|
||||
|
||||
def add_product_to_cart
|
||||
create(:line_item, variant: product.master, order: order)
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user