mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-04-03 06:59:14 +00:00
Merge branch 'master' into laura_and_will
Conflicts: app/assets/javascripts/darkswarm/services/order.js.coffee
This commit is contained in:
2
Gemfile
2
Gemfile
@@ -7,7 +7,7 @@ gem 'pg'
|
||||
gem 'spree', :github => 'openfoodfoundation/spree', :branch => '1-3-stable'
|
||||
gem 'spree_i18n', :github => 'spree/spree_i18n'
|
||||
gem 'spree_auth_devise', :github => 'spree/spree_auth_devise', :branch => '1-3-stable'
|
||||
gem 'spree_paypal_express', :github => 'openfoodfoundation/spree_paypal_express', :branch => '1-3-stable'
|
||||
gem 'spree_paypal_express', :github => "spree-contrib/better_spree_paypal_express", :branch => "1-3-stable"
|
||||
|
||||
gem 'comfortable_mexican_sofa'
|
||||
|
||||
|
||||
15
Gemfile.lock
15
Gemfile.lock
@@ -55,12 +55,13 @@ GIT
|
||||
spree_core (= 1.3.6.beta)
|
||||
|
||||
GIT
|
||||
remote: git://github.com/openfoodfoundation/spree_paypal_express.git
|
||||
revision: d2f38e5068c4b6979c2af7f64caca9e1df50de89
|
||||
remote: git://github.com/spree-contrib/better_spree_paypal_express.git
|
||||
revision: db135b89a289aaab951c1228bcc55871de0cbba7
|
||||
branch: 1-3-stable
|
||||
specs:
|
||||
spree_paypal_express (1.2.0)
|
||||
spree_core (~> 1.3.0)
|
||||
spree_paypal_express (2.0.3)
|
||||
paypal-sdk-merchant (= 1.106.1)
|
||||
spree_core (~> 1.3.4)
|
||||
|
||||
GIT
|
||||
remote: git://github.com/spree/deface.git
|
||||
@@ -341,6 +342,11 @@ GEM
|
||||
activesupport (>= 2.3.2)
|
||||
cocaine (>= 0.0.2)
|
||||
mime-types
|
||||
paypal-sdk-core (0.2.10)
|
||||
multi_json (~> 1.0)
|
||||
xml-simple
|
||||
paypal-sdk-merchant (1.106.1)
|
||||
paypal-sdk-core (~> 0.2.3)
|
||||
perftools.rb (2.0.1)
|
||||
pg (0.13.2)
|
||||
poltergeist (1.5.0)
|
||||
@@ -486,6 +492,7 @@ GEM
|
||||
whenever (0.9.2)
|
||||
activesupport (>= 2.3.4)
|
||||
chronic (>= 0.6.3)
|
||||
xml-simple (1.1.4)
|
||||
xpath (2.0.0)
|
||||
nokogiri (~> 1.3)
|
||||
zeus (0.13.3)
|
||||
|
||||
@@ -15,7 +15,11 @@
|
||||
//= require admin/spree_core
|
||||
//= require admin/spree_auth
|
||||
//= require admin/spree_promo
|
||||
//= require admin/spree_paypal_express
|
||||
//= require ./admin
|
||||
//= require ./enterprises/enterprises
|
||||
//= require ./payment_methods/payment_methods
|
||||
//= require ./products/products
|
||||
//= require ./shipping_methods/shipping_methods
|
||||
|
||||
//= require_tree .
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
angular.module("ofn.admin").controller "AdminOrderMgmtCtrl", [
|
||||
"$scope", "$http", "dataFetcher", "blankOption", "pendingChanges"
|
||||
($scope, $http, dataFetcher, blankOption, pendingChanges) ->
|
||||
"$scope", "$http", "dataFetcher", "blankOption", "pendingChanges", "VariantUnitManager", "OptionValueNamer",
|
||||
($scope, $http, dataFetcher, blankOption, pendingChanges, VariantUnitManager, OptionValueNamer) ->
|
||||
|
||||
$scope.initialiseVariables = ->
|
||||
start = daysFromToday -7
|
||||
@@ -134,30 +134,13 @@ angular.module("ofn.admin").controller "AdminOrderMgmtCtrl", [
|
||||
return false if !lineItem.units_variant.hasOwnProperty('unit_value') || !(lineItem.units_variant.unit_value > 0)
|
||||
true
|
||||
|
||||
$scope.getScale = (value, unitType) ->
|
||||
scaledValue = null
|
||||
validScales = []
|
||||
unitScales =
|
||||
'weight': [1.0, 1000.0, 1000000.0]
|
||||
'volume': [0.001, 1.0, 1000000.0]
|
||||
|
||||
validScales.unshift scale for scale in unitScales[unitType] when value/scale >= 1
|
||||
if validScales.length > 0
|
||||
validScales[0]
|
||||
else
|
||||
unitScales[unitType][0]
|
||||
|
||||
$scope.getUnitName = (scale, unitType) ->
|
||||
unitNames =
|
||||
'weight': {1.0: 'g', 1000.0: 'kg', 1000000.0: 'T'}
|
||||
'volume': {0.001: 'mL', 1.0: 'L', 1000000.0: 'ML'}
|
||||
unitNames[unitType][scale]
|
||||
|
||||
# How is this different to OptionValueNamer#name?
|
||||
# Should it be extracted to that class or VariantUnitManager?
|
||||
$scope.formattedValueWithUnitName = (value, unitsProduct, unitsVariant) ->
|
||||
# A Units Variant is an API object which holds unit properies of a variant
|
||||
if unitsProduct.hasOwnProperty("variant_unit") && (unitsProduct.variant_unit == "weight" || unitsProduct.variant_unit == "volume") && value > 0
|
||||
scale = $scope.getScale(value, unitsProduct.variant_unit)
|
||||
Math.round(value/scale * 1000)/1000 + " " + $scope.getUnitName(scale,unitsProduct.variant_unit)
|
||||
scale = VariantUnitManager.getScale(value, unitsProduct.variant_unit)
|
||||
Math.round(value/scale * 1000)/1000 + " " + VariantUnitManager.getUnitName(scale, unitsProduct.variant_unit)
|
||||
else
|
||||
''
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
angular.module("ofn.admin").controller "AdminProductEditCtrl", [
|
||||
"$scope", "$timeout", "$http", "dataFetcher", "DirtyProducts"
|
||||
($scope, $timeout, $http, dataFetcher, DirtyProducts) ->
|
||||
"$scope", "$timeout", "$http", "dataFetcher", "DirtyProducts", "VariantUnitManager",
|
||||
($scope, $timeout, $http, dataFetcher, DirtyProducts, VariantUnitManager) ->
|
||||
$scope.updateStatusMessage =
|
||||
text: ""
|
||||
style: {}
|
||||
@@ -14,15 +14,7 @@ angular.module("ofn.admin").controller "AdminProductEditCtrl", [
|
||||
taxons: {name: "Taxons", visible: false}
|
||||
available_on: {name: "Available On", visible: false}
|
||||
|
||||
$scope.variant_unit_options = [
|
||||
["Weight (g)", "weight_1"],
|
||||
["Weight (kg)", "weight_1000"],
|
||||
["Weight (T)", "weight_1000000"],
|
||||
["Volume (mL)", "volume_0.001"],
|
||||
["Volume (L)", "volume_1"],
|
||||
["Volume (ML)", "volume_1000000"],
|
||||
["Items", "items"]
|
||||
]
|
||||
$scope.variant_unit_options = VariantUnitManager.variantUnitOptions()
|
||||
|
||||
$scope.filterableColumns = [
|
||||
{ name: "Supplier", db_column: "supplier_name" },
|
||||
@@ -511,12 +503,12 @@ filterSubmitVariant = (variant) ->
|
||||
|
||||
toObjectWithIDKeys = (array) ->
|
||||
object = {}
|
||||
|
||||
|
||||
for i of array
|
||||
if array[i] instanceof Object and array[i].hasOwnProperty("id")
|
||||
object[array[i].id] = angular.copy(array[i])
|
||||
object[array[i].id].variants = toObjectWithIDKeys(array[i].variants) if array[i].hasOwnProperty("variants") and array[i].variants instanceof Array
|
||||
|
||||
|
||||
object
|
||||
|
||||
subset = (bigArray,smallArray) ->
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
angular.module("ofn.admin").directive "ofnDisplayAs", (optionValueNamer) ->
|
||||
angular.module("ofn.admin").directive "ofnDisplayAs", (OptionValueNamer) ->
|
||||
link: (scope, element, attrs) ->
|
||||
|
||||
scope.$watchCollection ->
|
||||
@@ -18,7 +18,7 @@ angular.module("ofn.admin").directive "ofnDisplayAs", (optionValueNamer) ->
|
||||
variant_unit: variant_unit
|
||||
variant_unit_name: scope.product.variant_unit_name
|
||||
|
||||
scope.placeholder_text = new optionValueNamer(variant_object).name()
|
||||
scope.placeholder_text = new OptionValueNamer(variant_object).name()
|
||||
|
||||
productUnitProperties = ->
|
||||
# get relevant product properties
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
angular.module("admin.enterprises")
|
||||
.controller "enterpriseCtrl", ($scope, Enterprise, PaymentMethods, ShippingMethods) ->
|
||||
$scope.Enterprise = Enterprise.enterprise
|
||||
$scope.PaymentMethods = PaymentMethods.paymentMethods
|
||||
$scope.ShippingMethods = ShippingMethods.shippingMethods
|
||||
|
||||
for PaymentMethod in $scope.PaymentMethods
|
||||
PaymentMethod.selected = if PaymentMethod.id in $scope.Enterprise.payment_method_ids then true else false
|
||||
|
||||
$scope.paymentMethodsColor = ->
|
||||
if $scope.PaymentMethods.length > 0
|
||||
if $scope.selectedPaymentMethodsCount() > 0 then "blue" else "red"
|
||||
else
|
||||
"red"
|
||||
|
||||
$scope.selectedPaymentMethodsCount = ->
|
||||
$scope.PaymentMethods.reduce (count, PaymentMethod) ->
|
||||
count++ if PaymentMethod.selected
|
||||
count
|
||||
, 0
|
||||
|
||||
for ShippingMethod in $scope.ShippingMethods
|
||||
ShippingMethod.selected = if ShippingMethod.id in $scope.Enterprise.shipping_method_ids then true else false
|
||||
|
||||
$scope.shippingMethodsColor = ->
|
||||
if $scope.ShippingMethods.length > 0
|
||||
if $scope.selectedShippingMethodsCount() > 0 then "blue" else "red"
|
||||
else
|
||||
"red"
|
||||
|
||||
$scope.selectedShippingMethodsCount = ->
|
||||
$scope.ShippingMethods.reduce (count, ShippingMethod) ->
|
||||
count++ if ShippingMethod.selected
|
||||
count
|
||||
, 0
|
||||
@@ -0,0 +1 @@
|
||||
angular.module("admin.enterprises", ["admin.payment_methods", "admin.shipping_methods"])
|
||||
@@ -0,0 +1,4 @@
|
||||
angular.module("admin.enterprises")
|
||||
.factory 'Enterprise', (enterprise) ->
|
||||
new class Enterprise
|
||||
enterprise: enterprise
|
||||
@@ -0,0 +1,4 @@
|
||||
angular.module("admin.payment_methods")
|
||||
.controller "paymentMethodCtrl", ($scope, PaymentMethods) ->
|
||||
$scope.findPaymentMethodByID = (id) ->
|
||||
$scope.PaymentMethod = PaymentMethods.findByID(id)
|
||||
@@ -0,0 +1 @@
|
||||
angular.module("admin.payment_methods", [])
|
||||
@@ -0,0 +1,8 @@
|
||||
angular.module("admin.payment_methods")
|
||||
.factory "PaymentMethods", (paymentMethods) ->
|
||||
new class PaymentMethods
|
||||
paymentMethods: paymentMethods
|
||||
|
||||
findByID: (id) ->
|
||||
for paymentMethod in @paymentMethods
|
||||
return paymentMethod if paymentMethod.id is id
|
||||
@@ -1,5 +1,5 @@
|
||||
angular.module("admin.products")
|
||||
.controller "unitsCtrl", ($scope, optionValueNamer) ->
|
||||
.controller "unitsCtrl", ($scope, VariantUnitManager, OptionValueNamer) ->
|
||||
$scope.product = { master: {} }
|
||||
$scope.product.master.product = $scope.product
|
||||
$scope.placeholder_text = ""
|
||||
@@ -24,20 +24,12 @@ angular.module("admin.products")
|
||||
$scope.product.master.unit_value *= $scope.product.variant_unit_scale if $scope.product.master.unit_value && $scope.product.variant_unit_scale
|
||||
$scope.product.master.unit_description = match[3]
|
||||
|
||||
$scope.placeholder_text = new optionValueNamer($scope.product.master).name()
|
||||
$scope.placeholder_text = new OptionValueNamer($scope.product.master).name()
|
||||
|
||||
$scope.variant_unit_options = [
|
||||
["Weight (g)", "weight_1"],
|
||||
["Weight (kg)", "weight_1000"],
|
||||
["Weight (T)", "weight_1000000"],
|
||||
["Volume (mL)", "volume_0.001"],
|
||||
["Volume (L)", "volume_1"],
|
||||
["Volume (ML)", "volume_1000000"],
|
||||
["Items", "items"]
|
||||
]
|
||||
$scope.variant_unit_options = VariantUnitManager.variantUnitOptions()
|
||||
|
||||
$scope.hasVariants = (product) ->
|
||||
Object.keys(product.variants).length > 0
|
||||
|
||||
$scope.hasUnit = (product) ->
|
||||
product.variant_unit_with_scale?
|
||||
product.variant_unit_with_scale?
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
angular.module("admin.products").factory "optionValueNamer", ->
|
||||
angular.module("admin.products").factory "OptionValueNamer", (VariantUnitManager) ->
|
||||
class OptionValueNamer
|
||||
constructor: (@variant) ->
|
||||
|
||||
@@ -18,18 +18,18 @@ angular.module("admin.products").factory "optionValueNamer", ->
|
||||
if @variant.unit_value?
|
||||
if @variant.product.variant_unit in ["weight", "volume"]
|
||||
[value, unit_name] = @option_value_value_unit_scaled()
|
||||
|
||||
|
||||
else
|
||||
value = @variant.unit_value
|
||||
unit_name = @variant.product.variant_unit_name
|
||||
# TODO needs to add pluralize to line below
|
||||
# unit_name = unit_name if value > 1
|
||||
|
||||
|
||||
value = parseInt(value, 10) if value == parseInt(value, 10)
|
||||
|
||||
|
||||
else
|
||||
value = unit_name = null
|
||||
|
||||
|
||||
[value, unit_name]
|
||||
|
||||
option_value_value_unit_scaled: ->
|
||||
@@ -40,27 +40,17 @@ angular.module("admin.products").factory "optionValueNamer", ->
|
||||
[value, unit_name]
|
||||
|
||||
scale_for_unit_value: ->
|
||||
units =
|
||||
'weight':
|
||||
1.0: 'g'
|
||||
1000.0: 'kg'
|
||||
1000000.0: 'T'
|
||||
'volume':
|
||||
0.001: 'mL'
|
||||
1.0: 'L'
|
||||
1000000.0: 'ML'
|
||||
|
||||
# Find the largest available unit where unit_value comes to >= 1 when expressed in it.
|
||||
# If there is none available where this is true, use the smallest available unit.
|
||||
unit = ([scale, unit_name] for scale, unit_name of units[@variant.product.variant_unit] when @variant.unit_value / scale >= 1).reduce (unit, [scale, unit_name]) ->
|
||||
unit = ([scale, unit_name] for scale, unit_name of VariantUnitManager.unitNames[@variant.product.variant_unit] when @variant.unit_value / scale >= 1).reduce (unit, [scale, unit_name]) ->
|
||||
if (unit && scale > unit[0]) || !unit?
|
||||
[scale, unit_name]
|
||||
else
|
||||
unit
|
||||
, null
|
||||
if !unit?
|
||||
unit = ([scale, unit_name] for scale, unit_name of units[@variant.product.variant_unit]).reduce (unit, [scale, unit_name]) ->
|
||||
unit = ([scale, unit_name] for scale, unit_name of VariantUnitManager.unitNames[@variant.product.variant_unit]).reduce (unit, [scale, unit_name]) ->
|
||||
if scale < unit[0] then [scale, unit_name] else unit
|
||||
, [Infinity,""]
|
||||
|
||||
unit
|
||||
unit
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
angular.module("admin.products").factory "VariantUnitManager", ->
|
||||
class VariantUnitManager
|
||||
@unitNames:
|
||||
'weight':
|
||||
1.0: 'g'
|
||||
1000.0: 'kg'
|
||||
1000000.0: 'T'
|
||||
'volume':
|
||||
0.001: 'mL'
|
||||
1.0: 'L'
|
||||
1000.0: 'kL'
|
||||
|
||||
@variantUnitOptions: ->
|
||||
options = for unit_type, scale_with_name of @unitNames
|
||||
unit_type_cap = unit_type[0].toUpperCase() + unit_type[1..-1]
|
||||
for scale in @unitScales(unit_type)
|
||||
name = @getUnitName(scale, unit_type)
|
||||
["#{unit_type_cap} (#{name})", "#{unit_type}_#{scale}"]
|
||||
options.push [['Items', 'items']]
|
||||
[].concat options...
|
||||
|
||||
@getScale: (value, unitType) ->
|
||||
scaledValue = null
|
||||
validScales = []
|
||||
unitScales = VariantUnitManager.unitScales(unitType)
|
||||
|
||||
validScales.unshift scale for scale in unitScales when value/scale >= 1
|
||||
if validScales.length > 0
|
||||
validScales[0]
|
||||
else
|
||||
unitScales[0]
|
||||
|
||||
@getUnitName: (scale, unitType) ->
|
||||
@unitNames[unitType][scale]
|
||||
|
||||
@unitScales: (unitType) ->
|
||||
(parseFloat(scale) for scale in Object.keys(@unitNames[unitType])).sort()
|
||||
@@ -0,0 +1,4 @@
|
||||
angular.module("admin.shipping_methods")
|
||||
.controller "shippingMethodCtrl", ($scope, ShippingMethods) ->
|
||||
$scope.findShippingMethodByID = (id) ->
|
||||
$scope.ShippingMethod = ShippingMethods.findByID(id)
|
||||
@@ -0,0 +1,8 @@
|
||||
angular.module("admin.shipping_methods")
|
||||
.factory "ShippingMethods", (shippingMethods) ->
|
||||
new class ShippingMethods
|
||||
shippingMethods: shippingMethods
|
||||
|
||||
findByID: (id) ->
|
||||
for shippingMethod in @shippingMethods
|
||||
return shippingMethod if shippingMethod.id is id
|
||||
@@ -0,0 +1 @@
|
||||
angular.module("admin.shipping_methods", [])
|
||||
@@ -18,13 +18,13 @@ div.sidebar_item
|
||||
max-height: 400px
|
||||
overflow-y: auto
|
||||
overflow-x: hidden
|
||||
border: solid #5498da
|
||||
border-width: 0px 1px 0px 1px
|
||||
&.red
|
||||
color: #DA5354
|
||||
border: solid #DA5354
|
||||
border-width: 0px 3px 0px 3px
|
||||
.list-item
|
||||
border: solid #DA5354
|
||||
border-width: 0px 3px 0px 3px
|
||||
a.alpha, span.alpha
|
||||
margin-left: -3px
|
||||
&.odd
|
||||
background-color: #fcf6ef
|
||||
&:hover
|
||||
@@ -33,9 +33,11 @@ div.sidebar_item
|
||||
color: #DA5354
|
||||
|
||||
.list-item
|
||||
span.alpha
|
||||
border: solid #5498da
|
||||
border-width: 0px 1px 0px 1px
|
||||
a.alpha, span.alpha
|
||||
font-weight: bold
|
||||
margin-left: -3px
|
||||
margin-left: -1px
|
||||
padding: 10px 2px 10px 5%
|
||||
overflow: hidden
|
||||
max-width: 160px
|
||||
@@ -55,6 +57,8 @@ div.sidebar_item
|
||||
&:hover
|
||||
color: #ffffff
|
||||
background-color: #9fc820
|
||||
a
|
||||
color: #ffffff
|
||||
|
||||
a.button
|
||||
color: #fff
|
||||
|
||||
@@ -6,7 +6,6 @@ class CheckoutController < Spree::CheckoutController
|
||||
prepend_before_filter :require_distributor_chosen
|
||||
|
||||
skip_before_filter :check_registration
|
||||
skip_before_filter :redirect_to_paypal_express_form_if_needed
|
||||
|
||||
include OrderCyclesHelper
|
||||
include EnterprisesHelper
|
||||
@@ -119,34 +118,13 @@ class CheckoutController < Spree::CheckoutController
|
||||
redirect_to main_app.shop_path
|
||||
end
|
||||
|
||||
# Overriding from github.com/spree/spree_paypal_express
|
||||
def redirect_to_paypal_express_form_if_needed
|
||||
return unless params[:order][:payments_attributes]
|
||||
|
||||
payment_method = Spree::PaymentMethod.find(params[:order][:payments_attributes].first[:payment_method_id])
|
||||
return unless payment_method.kind_of?(Spree::BillingIntegration::PaypalExpress) || payment_method.kind_of?(Spree::BillingIntegration::PaypalExpressUk)
|
||||
return unless payment_method.kind_of?(Spree::Gateway::PayPalExpress)
|
||||
|
||||
update_params = object_params.dup
|
||||
update_params.delete(:payments_attributes)
|
||||
if @order.update_attributes(update_params)
|
||||
fire_event('spree.checkout.update')
|
||||
render :edit and return unless apply_coupon_code
|
||||
end
|
||||
|
||||
load_order
|
||||
if not @order.errors.empty?
|
||||
render :edit and return
|
||||
end
|
||||
|
||||
render json: {path: main_app.paypal_payment_url(@order, :payment_method_id => payment_method.id)}, status: 200
|
||||
render json: {path: spree.paypal_express_url(payment_method_id: payment_method.id)}, status: 200
|
||||
true
|
||||
end
|
||||
|
||||
# Overriding to customize the cancel url
|
||||
def order_opts_with_new_cancel_return_url(order, payment_method_id, stage)
|
||||
opts = order_opts_without_new_cancel_return_url(order, payment_method_id, stage)
|
||||
opts[:cancel_return_url] = main_app.checkout_url
|
||||
opts
|
||||
end
|
||||
alias_method_chain :order_opts, :new_cancel_return_url
|
||||
end
|
||||
|
||||
@@ -5,13 +5,17 @@ Spree::Admin::ProductsController.class_eval do
|
||||
|
||||
respond_to :json, :only => :clone
|
||||
|
||||
respond_override create: { html: { success: lambda {
|
||||
if params[:button] == "add_another"
|
||||
redirect_to new_admin_product_path
|
||||
else
|
||||
redirect_to '/admin/products/bulk_edit'
|
||||
end
|
||||
} } }
|
||||
respond_override create: { html: {
|
||||
success: lambda {
|
||||
if params[:button] == "add_another"
|
||||
redirect_to new_admin_product_path
|
||||
else
|
||||
redirect_to '/admin/products/bulk_edit'
|
||||
end
|
||||
},
|
||||
failure: lambda {
|
||||
render :new
|
||||
} } }
|
||||
#respond_override :clone => { :json => {:success => lambda { redirect_to bulk_index_admin_products_url+"?q[id_eq]=#{@new.id}" } } }
|
||||
|
||||
def product_distributions
|
||||
|
||||
@@ -475,7 +475,7 @@ Spree::Admin::ReportsController.class_eval do
|
||||
@include_blank = 'All'
|
||||
|
||||
header = ["Hub", "Customer", "Email", "Phone", "Producer", "Product", "Variant", "Amount", "Item ($)", "Dist ($)", "Ship ($)", "Total ($)", "Paid?",
|
||||
"Shipping", "Delivery?", "Ship street", "Ship street 2", "Ship city", "Ship postcode", "Ship state"]
|
||||
"Shipping", "Delivery?", "Ship street", "Ship street 2", "Ship city", "Ship postcode", "Ship state", "Order notes"]
|
||||
|
||||
rsa = proc { |line_items| line_items.first.order.shipping_method.andand.require_ship_address }
|
||||
|
||||
@@ -499,7 +499,9 @@ Spree::Admin::ReportsController.class_eval do
|
||||
proc { |line_items| line_items.first.order.ship_address.andand.address2 if rsa.call(line_items) },
|
||||
proc { |line_items| line_items.first.order.ship_address.andand.city if rsa.call(line_items) },
|
||||
proc { |line_items| line_items.first.order.ship_address.andand.zipcode if rsa.call(line_items) },
|
||||
proc { |line_items| line_items.first.order.ship_address.andand.state if rsa.call(line_items) }]
|
||||
proc { |line_items| line_items.first.order.ship_address.andand.state if rsa.call(line_items) },
|
||||
|
||||
proc { |line_items| line_items.first.order.special_instructions }]
|
||||
|
||||
rules = [ { group_by: proc { |line_item| line_item.order.distributor },
|
||||
sort_by: proc { |distributor| distributor.name } },
|
||||
@@ -525,6 +527,8 @@ Spree::Admin::ReportsController.class_eval do
|
||||
proc { |line_items| "" },
|
||||
proc { |line_items| "" },
|
||||
proc { |line_items| "" },
|
||||
proc { |line_items| "" },
|
||||
|
||||
proc { |line_items| "" } ] },
|
||||
|
||||
{ group_by: proc { |line_item| line_item.variant.product },
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
Spree::CheckoutController.class_eval do
|
||||
|
||||
#def update
|
||||
#binding.pry
|
||||
#end
|
||||
include CheckoutHelper
|
||||
|
||||
private
|
||||
|
||||
@@ -24,21 +22,7 @@ Spree::CheckoutController.class_eval do
|
||||
end
|
||||
|
||||
def after_complete
|
||||
distributor = current_order.distributor
|
||||
token = current_order.token
|
||||
|
||||
session[:order_id] = nil
|
||||
clear_current_order_cache
|
||||
current_order(true)
|
||||
|
||||
current_order.set_distributor!(distributor)
|
||||
current_order.tokenized_permission.token = token
|
||||
current_order.tokenized_permission.save!
|
||||
session[:access_token] = token
|
||||
end
|
||||
|
||||
def clear_current_order_cache
|
||||
@current_order = nil
|
||||
reset_order
|
||||
end
|
||||
|
||||
def find_last_used_addresses(email)
|
||||
|
||||
20
app/controllers/spree/paypal_controller_decorator.rb
Normal file
20
app/controllers/spree/paypal_controller_decorator.rb
Normal file
@@ -0,0 +1,20 @@
|
||||
Spree::PaypalController.class_eval do
|
||||
include CheckoutHelper
|
||||
|
||||
after_filter :reset_order_when_complete, only: :confirm
|
||||
|
||||
def cancel
|
||||
flash[:notice] = t('flash.cancel', :scope => 'paypal')
|
||||
redirect_to main_app.checkout_path
|
||||
end
|
||||
|
||||
|
||||
private
|
||||
|
||||
def reset_order_when_complete
|
||||
if current_order.complete?
|
||||
flash[:success] = t(:order_processed_successfully)
|
||||
reset_order
|
||||
end
|
||||
end
|
||||
end
|
||||
25
app/helpers/admin/injection_helper.rb
Normal file
25
app/helpers/admin/injection_helper.rb
Normal file
@@ -0,0 +1,25 @@
|
||||
module Admin
|
||||
module InjectionHelper
|
||||
def admin_inject_enterprise
|
||||
admin_inject_json_ams "admin.enterprises", "enterprise", @enterprise, Api::Admin::EnterpriseSerializer
|
||||
end
|
||||
|
||||
def admin_inject_payment_methods
|
||||
admin_inject_json_ams_array "admin.payment_methods", "paymentMethods", @payment_methods, Api::Admin::IdNameSerializer
|
||||
end
|
||||
|
||||
def admin_inject_shipping_methods
|
||||
admin_inject_json_ams_array "admin.shipping_methods", "shippingMethods", @shipping_methods, Api::Admin::IdNameSerializer
|
||||
end
|
||||
|
||||
def admin_inject_json_ams(ngModule, name, data, serializer, opts = {})
|
||||
json = serializer.new(data).to_json
|
||||
render partial: "admin/json/injection_ams", locals: {ngModule: ngModule, name: name, json: json}
|
||||
end
|
||||
|
||||
def admin_inject_json_ams_array(ngModule, name, data, serializer, opts = {})
|
||||
json = ActiveModel::ArraySerializer.new(data, {each_serializer: serializer}.merge(opts)).to_json
|
||||
render partial: "admin/json/injection_ams", locals: {ngModule: ngModule, name: name, json: json}
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -25,4 +25,18 @@ module CheckoutHelper
|
||||
|
||||
render partial: "shared/validated_input", locals: {name: name, path: path, attributes: attributes}
|
||||
end
|
||||
|
||||
def reset_order
|
||||
distributor = current_order.distributor
|
||||
token = current_order.token
|
||||
|
||||
session[:order_id] = nil
|
||||
@current_order = nil
|
||||
current_order(true)
|
||||
|
||||
current_order.set_distributor!(distributor)
|
||||
current_order.tokenized_permission.token = token
|
||||
current_order.tokenized_permission.save!
|
||||
session[:access_token] = token
|
||||
end
|
||||
end
|
||||
|
||||
@@ -18,7 +18,7 @@ Spree::Product.class_eval do
|
||||
attr_accessible :variant_unit, :variant_unit_scale, :variant_unit_name, :unit_value, :unit_description, :notes, :images_attributes, :display_as
|
||||
|
||||
validates_presence_of :supplier
|
||||
validates_presence_of :primary_taxon
|
||||
validates :primary_taxon, presence: { message: "^Product Category can't be blank" }
|
||||
|
||||
validates_presence_of :variant_unit, if: :has_variants?
|
||||
validates_presence_of :variant_unit_scale,
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
/ insert_after "code[erb-silent]:contains('content_for :page_actions do')"
|
||||
|
||||
%li
|
||||
= button_link_to t(:new), spree.new_admin_payment_method_path, :icon => 'icon-plus' %>
|
||||
@@ -0,0 +1,4 @@
|
||||
/ insert_after "code[erb-silent]:contains('content_for :page_actions do')"
|
||||
|
||||
%li
|
||||
= button_link_to t(:new), spree.new_admin_shipping_method_path, :icon => 'icon-plus' %>
|
||||
3
app/serializers/api/admin/enterprise_serializer.rb
Normal file
3
app/serializers/api/admin/enterprise_serializer.rb
Normal file
@@ -0,0 +1,3 @@
|
||||
class Api::Admin::EnterpriseSerializer < ActiveModel::Serializer
|
||||
attributes :name, :id, :is_primary_producer, :is_distributor, :payment_method_ids, :shipping_method_ids
|
||||
end
|
||||
3
app/serializers/api/admin/id_name_serializer.rb
Normal file
3
app/serializers/api/admin/id_name_serializer.rb
Normal file
@@ -0,0 +1,3 @@
|
||||
class Api::Admin::IdNameSerializer < ActiveModel::Serializer
|
||||
attributes :id, :name
|
||||
end
|
||||
@@ -1,3 +1,3 @@
|
||||
class Api::IdSerializer < ActiveModel::Serializer
|
||||
attributes :id
|
||||
end
|
||||
end
|
||||
@@ -29,11 +29,11 @@
|
||||
.with-tip{'data-powertip' => "Select 'Producer' if you are a primary producer of food. Select 'Hub' if you want a shop-front. You can choose either or both."}
|
||||
%a What's this?
|
||||
.two.columns
|
||||
= f.check_box :is_distributor
|
||||
= f.check_box :is_distributor, 'ng-model' => 'Enterprise.is_distributor'
|
||||
|
||||
= f.label :is_distributor, 'Hub'
|
||||
.five.columns.omega
|
||||
= f.check_box :is_primary_producer
|
||||
= f.check_box :is_primary_producer, 'ng-model' => 'Enterprise.is_primary_producer'
|
||||
|
||||
= f.label :is_primary_producer, 'Producer'
|
||||
.row
|
||||
|
||||
9
app/views/admin/enterprises/_ng_form.html.haml
Normal file
9
app/views/admin/enterprises/_ng_form.html.haml
Normal file
@@ -0,0 +1,9 @@
|
||||
= admin_inject_enterprise
|
||||
= admin_inject_payment_methods
|
||||
= admin_inject_shipping_methods
|
||||
.sixteen.columns.alpha{ ng: { app: 'admin.enterprises', controller: 'enterpriseCtrl' } }
|
||||
.eleven.columns.alpha
|
||||
= render partial: 'form', :locals => { f: f }
|
||||
.one.column
|
||||
.four.columns.omega
|
||||
= render partial: 'sidebar', :locals => { f: f }
|
||||
@@ -1,48 +1,46 @@
|
||||
- payment_methods_color = @payment_methods.count > 0 ? (@enterprise.payment_methods.count > 0 ? "blue" : "red") : "red"
|
||||
.sidebar_item.four.columns.alpha#payment_methods
|
||||
.four.columns.alpha.header{ class: "#{payment_methods_color}" }
|
||||
.sidebar_item.four.columns.alpha#payment_methods{ ng: { show: 'Enterprise.is_distributor' } }
|
||||
.four.columns.alpha.header{ ng: { class: "paymentMethodsColor()" } }
|
||||
%span.four.columns.alpha.centered Payment Methods
|
||||
.four.columns.alpha.list{ class: "#{payment_methods_color}" }
|
||||
.four.columns.alpha.list{ ng: { class: "paymentMethodsColor()" } }
|
||||
- if @payment_methods.count > 0
|
||||
-# = hidden_field_tag "enterprise[payment_method_ids][]", []
|
||||
- @payment_methods.each do |payment_method|
|
||||
%a.four.columns.alpha.list-item{ class: "#{cycle('odd','even')}", href: "#{edit_admin_payment_method_path(payment_method)}" }
|
||||
%span.three.columns.alpha
|
||||
%span.four.columns.alpha.list-item{ class: "#{cycle('odd','even')}", ng: { controller: 'paymentMethodCtrl', init: "findPaymentMethodByID(#{payment_method.id})" } }
|
||||
%a.three.columns.alpha{ href: "#{edit_admin_payment_method_path(payment_method)}" }
|
||||
= payment_method.name
|
||||
%span.one.column.omega
|
||||
= f.check_box :payment_method_ids, { multiple: true }, payment_method.id, nil
|
||||
= f.check_box :payment_method_ids, { multiple: true, 'ng-model' => 'PaymentMethod.selected' }, payment_method.id, nil
|
||||
- else
|
||||
.four.columns.alpha.list-item
|
||||
%span.three.columns.alpha None Available
|
||||
%span.one.column.omega
|
||||
%span.icon-remove-sign
|
||||
%a.four.columns.alpha.button{ href: "#{new_admin_payment_method_path}", class: "#{payment_methods_color}" }
|
||||
%a.four.columns.alpha.button{ href: "#{new_admin_payment_method_path}", ng: { class: "paymentMethodsColor()" } }
|
||||
CREATE NEW
|
||||
%span.icon-arrow-right
|
||||
|
||||
- shipping_methods_color = @shipping_methods.count > 0 ? (@enterprise.shipping_methods.count > 0 ? "blue" : "red") : "red"
|
||||
.sidebar_item.four.columns.alpha#shipping_methods
|
||||
.four.columns.alpha.header{ class: "#{shipping_methods_color}" }
|
||||
.sidebar_item.four.columns.alpha#shipping_methods{ ng: { show: 'Enterprise.is_distributor' } }
|
||||
.four.columns.alpha.header{ ng: { class: "shippingMethodsColor()" } }
|
||||
%span.four.columns.alpha.centered Shipping Methods
|
||||
.four.columns.alpha.list{ class: "#{shipping_methods_color}" }
|
||||
.four.columns.alpha.list{ ng: { class: "shippingMethodsColor()" } }
|
||||
- if @shipping_methods.count > 0
|
||||
- @shipping_methods.each do |shipping_method|
|
||||
%a.four.columns.alpha.list-item{ class: "#{cycle('odd','even')}", href: "#{edit_admin_shipping_method_path(shipping_method)}" }
|
||||
%span.three.columns.alpha
|
||||
%span.four.columns.alpha.list-item{ class: "#{cycle('odd','even')}", ng: { controller: 'shippingMethodCtrl', init: "findShippingMethodByID(#{shipping_method.id})" } }
|
||||
%a.three.columns.alpha{ href: "#{edit_admin_shipping_method_path(shipping_method)}" }
|
||||
= shipping_method.name
|
||||
%span.one.column.omega
|
||||
= f.check_box :shipping_method_ids, { :multiple => true }, shipping_method.id, nil
|
||||
= f.check_box :shipping_method_ids, { :multiple => true, 'ng-model' => 'ShippingMethod.selected' }, shipping_method.id, nil
|
||||
- else
|
||||
.four.columns.alpha.list-item
|
||||
%span.three.columns.alpha None Available
|
||||
%span.one.column.omega
|
||||
%span.icon-remove-sign
|
||||
%a.four.columns.alpha.button{ href: "#{new_admin_shipping_method_path}", class: "#{shipping_methods_color}" }
|
||||
%a.four.columns.alpha.button{ href: "#{new_admin_shipping_method_path}", ng: { class: "shippingMethodsColor()" } }
|
||||
CREATE NEW
|
||||
%span.icon-arrow-right
|
||||
|
||||
- enterprise_fees_color = @enterprise_fees.count > 0 ? "blue" : "red"
|
||||
.sidebar_item.four.columns.alpha#enterprise_fees
|
||||
.sidebar_item.four.columns.alpha#enterprise_fees{ ng: { show: 'Enterprise.is_distributor' } }
|
||||
.four.columns.alpha.header{ class: "#{enterprise_fees_color}" }
|
||||
%span.four.columns.alpha.centered Enterprise Fees
|
||||
.four.columns.alpha.list{ class: "#{enterprise_fees_color}" }
|
||||
|
||||
@@ -5,10 +5,6 @@
|
||||
= @enterprise.name
|
||||
|
||||
= form_for [main_app, :admin, @enterprise] do |f|
|
||||
.eleven.columns.alpha
|
||||
= render :partial => 'form', :locals => { :f => f }
|
||||
.one.column
|
||||
.four.columns.omega
|
||||
= render :partial => 'sidebar', :locals => { :f => f }
|
||||
= render partial: 'ng_form', :locals => { f: f }
|
||||
.twelve.columns.alpha
|
||||
= render :partial => 'spree/admin/shared/edit_resource_links'
|
||||
= render partial: 'spree/admin/shared/edit_resource_links'
|
||||
|
||||
@@ -4,11 +4,6 @@
|
||||
New Enterprise
|
||||
|
||||
= form_for [main_app, :admin, @enterprise] do |f|
|
||||
.eleven.columns.alpha
|
||||
= render :partial => 'form', :locals => { :f => f }
|
||||
.one.column
|
||||
.four.columns.omega
|
||||
= render :partial => 'sidebar', :locals => { :f => f }
|
||||
= render partial: 'ng_form', :locals => { f: f }
|
||||
.twelve.columns.alpha
|
||||
-# Save, Save & Close and Cancel button
|
||||
= render :partial => 'spree/admin/shared/new_resource_links'
|
||||
= render partial: 'spree/admin/shared/new_resource_links'
|
||||
|
||||
2
app/views/admin/json/_injection_ams.html.haml
Normal file
2
app/views/admin/json/_injection_ams.html.haml
Normal file
@@ -0,0 +1,2 @@
|
||||
:javascript
|
||||
angular.module("#{ngModule}").value("#{name.to_s}", #{json})
|
||||
@@ -76,6 +76,10 @@
|
||||
.row
|
||||
.small-6.columns
|
||||
= validated_input "Phone", "order.ship_address.phone"
|
||||
.row
|
||||
.small-12.columns
|
||||
= f.text_area :special_instructions, label: "Any notes or custom delivery instructions?", size: "60x4", "ng-model" => "order.special_instructions"
|
||||
|
||||
.row
|
||||
.small-12.columns.text-right
|
||||
%button.primary{"ng-disabled" => "shipping.$invalid", "ng-click" => "next($event)", "ofn-focus" => "accordion['shipping']"} Next
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
= f.field_container :primary_taxon_id do
|
||||
= f.label :primary_taxon_id, t(:product_category)
|
||||
*
|
||||
%br
|
||||
= f.collection_select(:primary_taxon_id, Spree::Taxon.all, :id, :name, {:include_blank => true}, {:class => "select2 fullwidth"})
|
||||
= f.error_message_on :primary_taxon_id
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
- if @hubs.count > 0
|
||||
= f.hidden_field :distributor_ids, :multiple => true, value: nil
|
||||
- @hubs.each do |hub|
|
||||
%a.four.columns.alpha.list-item{ class: "#{cycle('odd','even')}", href: "#{main_app.edit_admin_enterprise_path(hub)}" }
|
||||
%span.three.columns.alpha
|
||||
%span.four.columns.alpha.list-item{ class: "#{cycle('odd','even')}" }
|
||||
%a.three.columns.alpha{ href: "#{main_app.edit_admin_enterprise_path(hub)}" }
|
||||
= hub.name
|
||||
%span.one.column.omega
|
||||
= f.check_box :distributor_ids, { multiple: true }, hub.id, nil
|
||||
|
||||
@@ -54,6 +54,9 @@ Ready for collection: <%= @order.order_cycle.pickup_time_for(@order.distributor)
|
||||
Collection instructions: <%= @order.order_cycle.pickup_instructions_for(@order.distributor) %>
|
||||
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% if @order.special_instructions.present? %>Order notes: <%= @order.special_instructions %>
|
||||
|
||||
<% end %>
|
||||
|
||||
Thanks for your support.
|
||||
|
||||
@@ -13,7 +13,8 @@ module.exports = function(config) {
|
||||
'app/assets/javascripts/shared/bindonce.min.js',
|
||||
'app/assets/javascripts/shared/ng-infinite-scroll.min.js',
|
||||
|
||||
'app/assets/javascripts/admin/*.js.*',
|
||||
'app/assets/javascripts/admin/*.js*',
|
||||
'app/assets/javascripts/admin/*/*.js*', // Pull in top level files in each folder first (often these are module declarations)
|
||||
'app/assets/javascripts/admin/**/*.js*',
|
||||
'app/assets/javascripts/darkswarm/*.js*',
|
||||
'app/assets/javascripts/darkswarm/**/*.js*',
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
# This migration comes from spree_paypal_express (originally 20130723042610)
|
||||
class CreateSpreePaypalExpressCheckouts < ActiveRecord::Migration
|
||||
def change
|
||||
create_table :spree_paypal_express_checkouts do |t|
|
||||
t.string :token
|
||||
t.string :payer_id
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,7 @@
|
||||
# This migration comes from spree_paypal_express (originally 20130808030836)
|
||||
class AddTransactionIdToSpreePaypalExpressCheckouts < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :spree_paypal_express_checkouts, :transaction_id, :string
|
||||
add_index :spree_paypal_express_checkouts, :transaction_id
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,6 @@
|
||||
# This migration comes from spree_paypal_express (originally 20130809013846)
|
||||
class AddStateToSpreePaypalExpressCheckouts < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :spree_paypal_express_checkouts, :state, :string, :default => "complete"
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,9 @@
|
||||
# This migration comes from spree_paypal_express (originally 20130809014319)
|
||||
class AddRefundedFieldsToSpreePaypalExpressCheckouts < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :spree_paypal_express_checkouts, :refund_transaction_id, :string
|
||||
add_column :spree_paypal_express_checkouts, :refunded_at, :datetime
|
||||
add_column :spree_paypal_express_checkouts, :refund_type, :string
|
||||
add_column :spree_paypal_express_checkouts, :created_at, :datetime
|
||||
end
|
||||
end
|
||||
13
db/migrate/20140723023713_switch_paypal_methods.rb
Normal file
13
db/migrate/20140723023713_switch_paypal_methods.rb
Normal file
@@ -0,0 +1,13 @@
|
||||
class SwitchPaypalMethods < ActiveRecord::Migration
|
||||
def up
|
||||
Spree::PaymentMethod.connection.execute <<EOS
|
||||
UPDATE spree_payment_methods
|
||||
SET type='Spree::Gateway::PayPalExpress'
|
||||
WHERE type IN ('Spree::BillingIntegration::PaypalExpress', 'Spree::BillingIntegration::PaypalExpressUk')
|
||||
EOS
|
||||
end
|
||||
|
||||
def down
|
||||
Spree::PaymentMethod.connection.execute "UPDATE spree_payment_methods SET type='Spree::BillingIntegration::PaypalExpress' WHERE type='Spree::Gateway::PayPalExpress'"
|
||||
end
|
||||
end
|
||||
15
db/schema.rb
15
db/schema.rb
@@ -11,7 +11,7 @@
|
||||
#
|
||||
# It's strongly recommended to check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(:version => 20140716051214) do
|
||||
ActiveRecord::Schema.define(:version => 20140723023713) do
|
||||
|
||||
create_table "adjustment_metadata", :force => true do |t|
|
||||
t.integer "adjustment_id"
|
||||
@@ -598,6 +598,19 @@ ActiveRecord::Schema.define(:version => 20140716051214) do
|
||||
t.string "payer_status"
|
||||
end
|
||||
|
||||
create_table "spree_paypal_express_checkouts", :force => true do |t|
|
||||
t.string "token"
|
||||
t.string "payer_id"
|
||||
t.string "transaction_id"
|
||||
t.string "state", :default => "complete"
|
||||
t.string "refund_transaction_id"
|
||||
t.datetime "refunded_at"
|
||||
t.string "refund_type"
|
||||
t.datetime "created_at"
|
||||
end
|
||||
|
||||
add_index "spree_paypal_express_checkouts", ["transaction_id"], :name => "index_spree_paypal_express_checkouts_on_transaction_id"
|
||||
|
||||
create_table "spree_pending_promotions", :force => true do |t|
|
||||
t.integer "user_id"
|
||||
t.integer "promotion_id"
|
||||
|
||||
@@ -44,7 +44,7 @@ module OpenFoodNetwork
|
||||
|
||||
def scale_for_unit_value
|
||||
units = {'weight' => {1.0 => 'g', 1000.0 => 'kg', 1000000.0 => 'T'},
|
||||
'volume' => {0.001 => 'mL', 1.0 => 'L', 1000000.0 => 'ML'}}
|
||||
'volume' => {0.001 => 'mL', 1.0 => 'L', 1000.0 => 'kL'}}
|
||||
|
||||
# Find the largest available unit where unit_value comes to >= 1 when expressed in it.
|
||||
# If there is none available where this is true, use the smallest available unit.
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
Spree::Config.use_s3 = false
|
||||
|
||||
@@ -19,8 +19,8 @@ ssh $1 "pg_dump -h localhost -U openfoodweb openfoodweb_production |gzip" |gunzi
|
||||
|
||||
|
||||
# -- Disable S3
|
||||
echo "Disabling S3 in development..."
|
||||
$RAILS_RUN script/disable_s3.rb
|
||||
echo "Preparing mirrored database..."
|
||||
$RAILS_RUN script/prepare_imported_db.rb
|
||||
|
||||
|
||||
# -- Mirror images
|
||||
|
||||
4
script/prepare_imported_db.rb
Normal file
4
script/prepare_imported_db.rb
Normal file
@@ -0,0 +1,4 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
Spree::Config.use_s3 = false
|
||||
Spree::PaymentMethod.update_all environment: 'development'
|
||||
@@ -108,7 +108,7 @@ describe CheckoutController do
|
||||
end
|
||||
|
||||
describe "Paypal routing" do
|
||||
let(:payment_method) { create(:payment_method, type: "Spree::BillingIntegration::PaypalExpress") }
|
||||
let(:payment_method) { create(:payment_method, type: "Spree::Gateway::PayPalExpress") }
|
||||
before do
|
||||
controller.stub(:current_distributor).and_return(distributor)
|
||||
controller.stub(:current_order_cycle).and_return(order_cycle)
|
||||
@@ -121,10 +121,5 @@ describe CheckoutController do
|
||||
order.stub(:state).and_return "payment"
|
||||
spree_post :update, order: {payments_attributes: [{payment_method_id: payment_method.id}]}
|
||||
end
|
||||
|
||||
it "should override the cancel return url" do
|
||||
controller.stub(:params).and_return({payment_method_id: payment_method.id})
|
||||
controller.send(:order_opts, order, payment_method.id, 'payment')[:cancel_return_url].should == checkout_url
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
10
spec/controllers/spree/paypal_controller_spec.rb
Normal file
10
spec/controllers/spree/paypal_controller_spec.rb
Normal file
@@ -0,0 +1,10 @@
|
||||
require 'spec_helper'
|
||||
|
||||
module Spree
|
||||
describe PaypalController do
|
||||
it "should redirect back to checkout after cancel" do
|
||||
spree_get :cancel
|
||||
response.should redirect_to checkout_path
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -125,9 +125,17 @@ feature %q{
|
||||
fill_in 'enterprise_name', :with => 'Eaterprises'
|
||||
fill_in 'enterprise_description', :with => 'Connecting farmers and eaters'
|
||||
fill_in 'enterprise_long_description', :with => 'Zombie ipsum reversus ab viral inferno, nam rick grimes malum cerebro.'
|
||||
|
||||
|
||||
# Check Angularjs switching of sidebar elements
|
||||
uncheck 'enterprise_is_primary_producer'
|
||||
uncheck 'enterprise_is_distributor'
|
||||
page.should have_selector "#payment_methods", visible: false
|
||||
page.should have_selector "#shipping_methods", visible: false
|
||||
page.should have_selector "#enterprise_fees", visible: false
|
||||
check 'enterprise_is_distributor'
|
||||
page.should have_selector "#payment_methods"
|
||||
page.should have_selector "#shipping_methods"
|
||||
page.should have_selector "#enterprise_fees"
|
||||
|
||||
select eg1.name, from: 'enterprise_group_ids'
|
||||
|
||||
|
||||
@@ -60,7 +60,14 @@ feature "As a consumer I want to check out my cart", js: true do
|
||||
describe "with payment methods" do
|
||||
let!(:pm1) { create(:payment_method, distributors: [distributor], name: "Roger rabbit", type: "Spree::PaymentMethod::Check") }
|
||||
let!(:pm2) { create(:payment_method, distributors: [distributor]) }
|
||||
let!(:pm3) { create(:payment_method, distributors: [distributor], name: "Paypal", type: "Spree::BillingIntegration::PaypalExpress") }
|
||||
let!(:pm3) do
|
||||
Spree::Gateway::PayPalExpress.create!(name: "Paypal", environment: 'test').tap do |pm|
|
||||
pm.distributors << distributor
|
||||
pm.preferred_login = 'devnull-facilitator_api1.rohanmitchell.com'
|
||||
pm.preferred_password = '1406163716'
|
||||
pm.preferred_signature = 'AFcWxV21C7fd0v3bYYYRCpSSRl31AaTntNJ-AjvUJkWf4dgJIvcLsf1V'
|
||||
end
|
||||
end
|
||||
|
||||
before do
|
||||
visit checkout_path
|
||||
@@ -71,6 +78,7 @@ feature "As a consumer I want to check out my cart", js: true do
|
||||
it "shows all available payment methods" do
|
||||
page.should have_content pm1.name
|
||||
page.should have_content pm2.name
|
||||
page.should have_content pm3.name
|
||||
end
|
||||
|
||||
describe "Purchasing" do
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
describe "enterpriseCtrl", ->
|
||||
ctrl = null
|
||||
scope = null
|
||||
Enterprise = null
|
||||
PaymentMethods = null
|
||||
ShippingMethods = null
|
||||
|
||||
beforeEach ->
|
||||
module('admin.enterprises')
|
||||
Enterprise =
|
||||
enterprise:
|
||||
payment_method_ids: [ 1, 3 ]
|
||||
shipping_method_ids: [ 2, 4 ]
|
||||
PaymentMethods =
|
||||
paymentMethods: [ { id: 1 }, { id: 2 }, { id: 3 }, { id: 4 } ]
|
||||
ShippingMethods =
|
||||
shippingMethods: [ { id: 1 }, { id: 2 }, { id: 3 }, { id: 4 } ]
|
||||
|
||||
inject ($controller) ->
|
||||
scope = {}
|
||||
ctrl = $controller 'enterpriseCtrl', {$scope: scope, Enterprise: Enterprise, PaymentMethods: PaymentMethods, ShippingMethods: ShippingMethods}
|
||||
|
||||
describe "initialisation", ->
|
||||
it "stores enterprise", ->
|
||||
expect(scope.Enterprise).toEqual Enterprise.enterprise
|
||||
|
||||
it "stores payment methods", ->
|
||||
expect(scope.PaymentMethods).toBe PaymentMethods.paymentMethods
|
||||
|
||||
it "stores shipping methods", ->
|
||||
expect(scope.ShippingMethods).toBe ShippingMethods.shippingMethods
|
||||
|
||||
it "sets the selected property of each payment method", ->
|
||||
expect(PaymentMethods.paymentMethods[0].selected).toBe true
|
||||
expect(PaymentMethods.paymentMethods[1].selected).toBe false
|
||||
expect(PaymentMethods.paymentMethods[2].selected).toBe true
|
||||
expect(PaymentMethods.paymentMethods[3].selected).toBe false
|
||||
|
||||
it "sets the selected property of each shipping method", ->
|
||||
expect(ShippingMethods.shippingMethods[0].selected).toBe false
|
||||
expect(ShippingMethods.shippingMethods[1].selected).toBe true
|
||||
expect(ShippingMethods.shippingMethods[2].selected).toBe false
|
||||
expect(ShippingMethods.shippingMethods[3].selected).toBe true
|
||||
|
||||
describe "determining payment method colour", ->
|
||||
it "returns 'blue' when at least one payment method is selected", ->
|
||||
scope.PaymentMethods = [ { id: 1 } ]
|
||||
spyOn(scope, "selectedPaymentMethodsCount").andReturn 1
|
||||
expect(scope.paymentMethodsColor()).toBe "blue"
|
||||
|
||||
it "returns 'red' when no payment methods are selected", ->
|
||||
scope.PaymentMethods = [ { id: 1 } ]
|
||||
spyOn(scope, "selectedPaymentMethodsCount").andReturn 0
|
||||
expect(scope.paymentMethodsColor()).toBe "red"
|
||||
|
||||
it "returns 'red' when no payment methods exist", ->
|
||||
scope.PaymentMethods = [ ]
|
||||
spyOn(scope, "selectedPaymentMethodsCount").andReturn 1
|
||||
expect(scope.paymentMethodsColor()).toBe "red"
|
||||
|
||||
describe "counting selected payment methods", ->
|
||||
it "counts only payment methods with selected: true", ->
|
||||
scopePaymentMethods = [ { selected: true }, { selected: false }, { selected: false }, { selected: true } ]
|
||||
expect(scope.selectedPaymentMethodsCount()).toBe 2
|
||||
|
||||
describe "determining shipping method colour", ->
|
||||
it "returns 'blue' when at least one shipping method is selected", ->
|
||||
scope.ShippingMethods = [ { id: 1 } ]
|
||||
spyOn(scope, "selectedShippingMethodsCount").andReturn 1
|
||||
expect(scope.shippingMethodsColor()).toBe "blue"
|
||||
|
||||
it "returns 'red' when no shipping methods are selected", ->
|
||||
scope.ShippingMethods = [ { id: 1 } ]
|
||||
spyOn(scope, "selectedShippingMethodsCount").andReturn 0
|
||||
expect(scope.shippingMethodsColor()).toBe "red"
|
||||
|
||||
it "returns 'red' when no shipping method exist", ->
|
||||
scope.ShippingMethods = [ ]
|
||||
spyOn(scope, "selectedShippingMethodsCount").andReturn 1
|
||||
expect(scope.shippingMethodsColor()).toBe "red"
|
||||
|
||||
describe "counting selected shipping methods", ->
|
||||
it "counts only shipping methods with selected: true", ->
|
||||
scope.ShippingMethods = [ { selected: true }, { selected: true }, { selected: false }, { selected: true } ]
|
||||
expect(scope.selectedShippingMethodsCount()).toBe 3
|
||||
@@ -0,0 +1,12 @@
|
||||
describe "Enterprise service", ->
|
||||
Enterprise = null
|
||||
enterprise = { name: "test ent name" }
|
||||
beforeEach ->
|
||||
module 'admin.enterprises'
|
||||
angular.module('admin.enterprises').value('enterprise', enterprise)
|
||||
|
||||
inject ($injector) ->
|
||||
Enterprise = $injector.get("Enterprise")
|
||||
|
||||
it "stores enterprise value as Enterprise.enterprise", ->
|
||||
expect(Enterprise.enterprise).toBe enterprise
|
||||
@@ -1,17 +1,17 @@
|
||||
describe "Option Value Namer", ->
|
||||
optionValueNamer = null
|
||||
OptionValueNamer = null
|
||||
|
||||
beforeEach ->
|
||||
module "ofn.admin"
|
||||
|
||||
beforeEach inject (_optionValueNamer_) ->
|
||||
optionValueNamer = _optionValueNamer_
|
||||
beforeEach inject (_OptionValueNamer_) ->
|
||||
OptionValueNamer = _OptionValueNamer_
|
||||
|
||||
describe "generating option value name", ->
|
||||
v = namer = null
|
||||
beforeEach ->
|
||||
v = {}
|
||||
namer = new optionValueNamer(v)
|
||||
namer = new OptionValueNamer(v)
|
||||
|
||||
it "when description is blank", ->
|
||||
v.unit_description = null
|
||||
@@ -43,7 +43,7 @@ describe "Option Value Namer", ->
|
||||
beforeEach ->
|
||||
p = {}
|
||||
v = { product: p }
|
||||
namer = new optionValueNamer(v)
|
||||
namer = new OptionValueNamer(v)
|
||||
|
||||
it "returns true when the product has a scale", ->
|
||||
p.variant_unit_scale = 1000
|
||||
@@ -58,7 +58,7 @@ describe "Option Value Namer", ->
|
||||
beforeEach ->
|
||||
p = {}
|
||||
v = { product: p }
|
||||
namer = new optionValueNamer(v)
|
||||
namer = new OptionValueNamer(v)
|
||||
|
||||
it "generates simple values", ->
|
||||
p.variant_unit = 'weight'
|
||||
@@ -87,7 +87,7 @@ describe "Option Value Namer", ->
|
||||
expect(namer.option_value_value_unit()).toEqual [100, unit]
|
||||
|
||||
it "generates values for all volume scales", ->
|
||||
for units in [[0.001, 'mL'], [1.0, 'L'], [1000000.0, 'ML']]
|
||||
for units in [[0.001, 'mL'], [1.0, 'L'], [1000.0, 'kL']]
|
||||
[scale, unit] = units
|
||||
p.variant_unit = 'volume'
|
||||
p.variant_unit_scale = scale
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
describe "VariantUnitManager", ->
|
||||
VariantUnitManager = null
|
||||
|
||||
beforeEach ->
|
||||
module "admin.products"
|
||||
|
||||
beforeEach inject (_VariantUnitManager_) ->
|
||||
VariantUnitManager = _VariantUnitManager_
|
||||
|
||||
describe "getScale", ->
|
||||
it "returns the largest scale for which value/scale is greater than 1", ->
|
||||
expect(VariantUnitManager.getScale(1.2,"weight")).toEqual 1.0
|
||||
expect(VariantUnitManager.getScale(1000,"weight")).toEqual 1000.0
|
||||
expect(VariantUnitManager.getScale(0.0012,"volume")).toEqual 0.001
|
||||
expect(VariantUnitManager.getScale(1001,"volume")).toEqual 1000.0
|
||||
|
||||
it "returns the smallest unit available when value is smaller", ->
|
||||
expect(VariantUnitManager.getScale(0.4,"weight")).toEqual 1
|
||||
expect(VariantUnitManager.getScale(0.0004,"volume")).toEqual 0.001
|
||||
|
||||
describe "getUnitName", ->
|
||||
it "returns the unit name based on the scale and unit type (weight/volume) provided", ->
|
||||
expect(VariantUnitManager.getUnitName(1, "weight")).toEqual "g"
|
||||
expect(VariantUnitManager.getUnitName(1000, "weight")).toEqual "kg"
|
||||
expect(VariantUnitManager.getUnitName(1000000, "weight")).toEqual "T"
|
||||
expect(VariantUnitManager.getUnitName(0.001, "volume")).toEqual "mL"
|
||||
expect(VariantUnitManager.getUnitName(1, "volume")).toEqual "L"
|
||||
expect(VariantUnitManager.getUnitName(1000, "volume")).toEqual "kL"
|
||||
|
||||
describe "unitScales", ->
|
||||
it "returns a set of scales for unit type weight", ->
|
||||
expect(VariantUnitManager.unitScales('weight')).toEqual [1.0, 1000.0, 1000000.0]
|
||||
|
||||
it "returns a set of scales for unit type volume", ->
|
||||
expect(VariantUnitManager.unitScales('volume')).toEqual [0.001, 1.0, 1000.0]
|
||||
|
||||
describe "variantUnitOptions", ->
|
||||
it "returns an array of options", ->
|
||||
expect(VariantUnitManager.variantUnitOptions()).toEqual [
|
||||
["Weight (g)", "weight_1"],
|
||||
["Weight (kg)", "weight_1000"],
|
||||
["Weight (T)", "weight_1000000"],
|
||||
["Volume (mL)", "volume_0.001"],
|
||||
["Volume (L)", "volume_1"],
|
||||
["Volume (kL)", "volume_1000"],
|
||||
["Items", "items"]
|
||||
]
|
||||
@@ -1,12 +1,13 @@
|
||||
describe "AdminOrderMgmtCtrl", ->
|
||||
ctrl = scope = httpBackend = null
|
||||
ctrl = scope = httpBackend = VariantUnitManager = null
|
||||
|
||||
beforeEach ->
|
||||
module "ofn.admin"
|
||||
beforeEach inject(($controller, $rootScope, $httpBackend) ->
|
||||
beforeEach inject(($controller, $rootScope, $httpBackend, _VariantUnitManager_) ->
|
||||
scope = $rootScope.$new()
|
||||
ctrl = $controller
|
||||
httpBackend = $httpBackend
|
||||
VariantUnitManager = _VariantUnitManager_
|
||||
spyOn(window, "formatDate").andReturn "SomeDate"
|
||||
|
||||
ctrl "AdminOrderMgmtCtrl", {$scope: scope}
|
||||
@@ -337,36 +338,16 @@ describe "AdminOrderMgmtCtrl", ->
|
||||
|
||||
it "calls Math.round with the quotient of scale and value, multiplied by 1000", ->
|
||||
unitsVariant = { variant_unit: "weight" }
|
||||
spyOn(scope,"getScale").andReturn 5
|
||||
scope.formattedValueWithUnitName(10,unitsVariant)
|
||||
spyOn(VariantUnitManager, "getScale").andReturn 5
|
||||
scope.formattedValueWithUnitName(10, unitsVariant)
|
||||
expect(Math.round).toHaveBeenCalledWith 10/5 * 1000
|
||||
|
||||
it "returns the result of Math.round divided by 1000, followed by the result of getUnitName", ->
|
||||
unitsVariant = { variant_unit: "weight" }
|
||||
spyOn(scope,"getScale").andReturn 1000
|
||||
spyOn(scope,"getUnitName").andReturn "kg"
|
||||
spyOn(VariantUnitManager, "getScale").andReturn 1000
|
||||
spyOn(VariantUnitManager, "getUnitName").andReturn "kg"
|
||||
expect(scope.formattedValueWithUnitName(2000,unitsVariant)).toEqual "2 kg"
|
||||
|
||||
describe "getScale", ->
|
||||
it "returns the largest scale for which value/scale is greater than 1", ->
|
||||
expect(scope.getScale(1.2,"weight")).toEqual 1.0
|
||||
expect(scope.getScale(1000,"weight")).toEqual 1000.0
|
||||
expect(scope.getScale(0.0012,"volume")).toEqual 0.001
|
||||
expect(scope.getScale(1001,"volume")).toEqual 1.0
|
||||
|
||||
it "returns the smallest unit available when value is smaller", ->
|
||||
expect(scope.getScale(0.4,"weight")).toEqual 1
|
||||
expect(scope.getScale(0.0004,"volume")).toEqual 0.001
|
||||
|
||||
describe "getUnitName", ->
|
||||
it "returns the unit name based on the scale and unit type (weight/volume) provided", ->
|
||||
expect(scope.getUnitName(1,"weight")).toEqual "g"
|
||||
expect(scope.getUnitName(1000,"weight")).toEqual "kg"
|
||||
expect(scope.getUnitName(1000000,"weight")).toEqual "T"
|
||||
expect(scope.getUnitName(0.001,"volume")).toEqual "mL"
|
||||
expect(scope.getUnitName(1,"volume")).toEqual "L"
|
||||
expect(scope.getUnitName(1000000,"volume")).toEqual "ML"
|
||||
|
||||
describe "managing pending changes", ->
|
||||
dataSubmitter = pendingChangesService = null
|
||||
|
||||
|
||||
@@ -94,7 +94,7 @@ module OpenFoodNetwork
|
||||
end
|
||||
|
||||
it "generates values for all volume scales" do
|
||||
[[0.001, 'mL'], [1.0, 'L'], [1000000.0, 'ML']].each do |scale, unit|
|
||||
[[0.001, 'mL'], [1.0, 'L'], [1000.0, 'kL']].each do |scale, unit|
|
||||
p = double(:product, variant_unit: 'volume', variant_unit_scale: scale)
|
||||
v.stub(:product) { p }
|
||||
v.stub(:unit_value) { 100 * scale }
|
||||
@@ -133,4 +133,4 @@ module OpenFoodNetwork
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
7
spec/serializers/admin/enterprise_serializer_spec.rb
Normal file
7
spec/serializers/admin/enterprise_serializer_spec.rb
Normal file
@@ -0,0 +1,7 @@
|
||||
describe Api::Admin::EnterpriseSerializer do
|
||||
let(:enterprise) { create(:distributor_enterprise) }
|
||||
it "serializes an enterprise" do
|
||||
serializer = Api::Admin::EnterpriseSerializer.new enterprise
|
||||
serializer.to_json.should match enterprise.name
|
||||
end
|
||||
end
|
||||
@@ -4,18 +4,18 @@ describe Api::EnterpriseSerializer do
|
||||
let(:enterprise) { create(:distributor_enterprise) }
|
||||
let(:taxon) { create(:taxon) }
|
||||
it "serializes an enterprise" do
|
||||
serializer = Api::EnterpriseSerializer.new enterprise
|
||||
serializer.to_json.should match enterprise.name
|
||||
serializer = Api::EnterpriseSerializer.new enterprise
|
||||
serializer.to_json.should match enterprise.name
|
||||
end
|
||||
|
||||
it "includes distributed taxons" do
|
||||
enterprise.stub(:distributed_taxons).and_return [taxon]
|
||||
serializer = Api::EnterpriseSerializer.new enterprise
|
||||
serializer = Api::EnterpriseSerializer.new enterprise
|
||||
serializer.to_json.should match taxon.id.to_s
|
||||
end
|
||||
|
||||
it "will render urls" do
|
||||
serializer = Api::EnterpriseSerializer.new enterprise
|
||||
serializer = Api::EnterpriseSerializer.new enterprise
|
||||
serializer.to_json.should match "map-icon-hub.svg"
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user