diff --git a/Gemfile b/Gemfile index b00ffa4cc1..0ed6cfc3f3 100644 --- a/Gemfile +++ b/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' diff --git a/Gemfile.lock b/Gemfile.lock index 19de512883..4a5a94f0a8 100644 --- a/Gemfile.lock +++ b/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) diff --git a/app/assets/javascripts/admin/all.js b/app/assets/javascripts/admin/all.js index 3fdd45585a..4c763ec411 100644 --- a/app/assets/javascripts/admin/all.js +++ b/app/assets/javascripts/admin/all.js @@ -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 . diff --git a/app/assets/javascripts/admin/bulk_order_management.js.coffee b/app/assets/javascripts/admin/bulk_order_management.js.coffee index 9ba34790a8..d545245eeb 100644 --- a/app/assets/javascripts/admin/bulk_order_management.js.coffee +++ b/app/assets/javascripts/admin/bulk_order_management.js.coffee @@ -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 '' diff --git a/app/assets/javascripts/admin/bulk_product_update.js.coffee b/app/assets/javascripts/admin/bulk_product_update.js.coffee index ba9c1fa18d..8fc088fc97 100644 --- a/app/assets/javascripts/admin/bulk_product_update.js.coffee +++ b/app/assets/javascripts/admin/bulk_product_update.js.coffee @@ -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) -> diff --git a/app/assets/javascripts/admin/directives/display_as.js.coffee b/app/assets/javascripts/admin/directives/display_as.js.coffee index 21f83ebf9f..5e4c5f7417 100644 --- a/app/assets/javascripts/admin/directives/display_as.js.coffee +++ b/app/assets/javascripts/admin/directives/display_as.js.coffee @@ -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 diff --git a/app/assets/javascripts/admin/enterprises/controllers/enterprise_controller.js.coffee b/app/assets/javascripts/admin/enterprises/controllers/enterprise_controller.js.coffee new file mode 100644 index 0000000000..cf182df494 --- /dev/null +++ b/app/assets/javascripts/admin/enterprises/controllers/enterprise_controller.js.coffee @@ -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 \ No newline at end of file diff --git a/app/assets/javascripts/admin/enterprises/enterprises.js.coffee b/app/assets/javascripts/admin/enterprises/enterprises.js.coffee new file mode 100644 index 0000000000..cdf90cfb51 --- /dev/null +++ b/app/assets/javascripts/admin/enterprises/enterprises.js.coffee @@ -0,0 +1 @@ +angular.module("admin.enterprises", ["admin.payment_methods", "admin.shipping_methods"]) \ No newline at end of file diff --git a/app/assets/javascripts/admin/enterprises/services/enterprise.js.coffee b/app/assets/javascripts/admin/enterprises/services/enterprise.js.coffee new file mode 100644 index 0000000000..b6e6a6147e --- /dev/null +++ b/app/assets/javascripts/admin/enterprises/services/enterprise.js.coffee @@ -0,0 +1,4 @@ +angular.module("admin.enterprises") + .factory 'Enterprise', (enterprise) -> + new class Enterprise + enterprise: enterprise \ No newline at end of file diff --git a/app/assets/javascripts/admin/payment_methods/controllers/payment_method_controller.js.coffee b/app/assets/javascripts/admin/payment_methods/controllers/payment_method_controller.js.coffee new file mode 100644 index 0000000000..092fd5bbd2 --- /dev/null +++ b/app/assets/javascripts/admin/payment_methods/controllers/payment_method_controller.js.coffee @@ -0,0 +1,4 @@ +angular.module("admin.payment_methods") + .controller "paymentMethodCtrl", ($scope, PaymentMethods) -> + $scope.findPaymentMethodByID = (id) -> + $scope.PaymentMethod = PaymentMethods.findByID(id) \ No newline at end of file diff --git a/app/assets/javascripts/admin/payment_methods/payment_methods.js.coffee b/app/assets/javascripts/admin/payment_methods/payment_methods.js.coffee new file mode 100644 index 0000000000..e75142ae0d --- /dev/null +++ b/app/assets/javascripts/admin/payment_methods/payment_methods.js.coffee @@ -0,0 +1 @@ +angular.module("admin.payment_methods", []) \ No newline at end of file diff --git a/app/assets/javascripts/admin/payment_methods/services/payment_methods.js.coffee b/app/assets/javascripts/admin/payment_methods/services/payment_methods.js.coffee new file mode 100644 index 0000000000..53fdcb93e4 --- /dev/null +++ b/app/assets/javascripts/admin/payment_methods/services/payment_methods.js.coffee @@ -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 diff --git a/app/assets/javascripts/admin/products/units_controller.js.coffee b/app/assets/javascripts/admin/products/units_controller.js.coffee index e253e701fa..db005e490a 100644 --- a/app/assets/javascripts/admin/products/units_controller.js.coffee +++ b/app/assets/javascripts/admin/products/units_controller.js.coffee @@ -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? \ No newline at end of file + product.variant_unit_with_scale? diff --git a/app/assets/javascripts/admin/services/option_value_namer.js.coffee b/app/assets/javascripts/admin/services/option_value_namer.js.coffee index b497e3aef2..1bea9b82f1 100644 --- a/app/assets/javascripts/admin/services/option_value_namer.js.coffee +++ b/app/assets/javascripts/admin/services/option_value_namer.js.coffee @@ -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 \ No newline at end of file + unit diff --git a/app/assets/javascripts/admin/services/variant_unit_manager.js.coffee b/app/assets/javascripts/admin/services/variant_unit_manager.js.coffee new file mode 100644 index 0000000000..9e15acfc6a --- /dev/null +++ b/app/assets/javascripts/admin/services/variant_unit_manager.js.coffee @@ -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() diff --git a/app/assets/javascripts/admin/shipping_methods/controllers/shipping_method_controller.js.coffee b/app/assets/javascripts/admin/shipping_methods/controllers/shipping_method_controller.js.coffee new file mode 100644 index 0000000000..dabe52574e --- /dev/null +++ b/app/assets/javascripts/admin/shipping_methods/controllers/shipping_method_controller.js.coffee @@ -0,0 +1,4 @@ +angular.module("admin.shipping_methods") + .controller "shippingMethodCtrl", ($scope, ShippingMethods) -> + $scope.findShippingMethodByID = (id) -> + $scope.ShippingMethod = ShippingMethods.findByID(id) \ No newline at end of file diff --git a/app/assets/javascripts/admin/shipping_methods/services/shipping_methods.js.coffee b/app/assets/javascripts/admin/shipping_methods/services/shipping_methods.js.coffee new file mode 100644 index 0000000000..eddc1aaf50 --- /dev/null +++ b/app/assets/javascripts/admin/shipping_methods/services/shipping_methods.js.coffee @@ -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 diff --git a/app/assets/javascripts/admin/shipping_methods/shipping_methods.js.coffee b/app/assets/javascripts/admin/shipping_methods/shipping_methods.js.coffee new file mode 100644 index 0000000000..99aeb9566d --- /dev/null +++ b/app/assets/javascripts/admin/shipping_methods/shipping_methods.js.coffee @@ -0,0 +1 @@ +angular.module("admin.shipping_methods", []) \ No newline at end of file diff --git a/app/assets/stylesheets/admin/sidebar-item.css.sass b/app/assets/stylesheets/admin/sidebar-item.css.sass index fc19154e94..ee7542f138 100644 --- a/app/assets/stylesheets/admin/sidebar-item.css.sass +++ b/app/assets/stylesheets/admin/sidebar-item.css.sass @@ -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 diff --git a/app/controllers/checkout_controller.rb b/app/controllers/checkout_controller.rb index 77137f5940..8e2a33bd56 100644 --- a/app/controllers/checkout_controller.rb +++ b/app/controllers/checkout_controller.rb @@ -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 diff --git a/app/controllers/spree/admin/products_controller_decorator.rb b/app/controllers/spree/admin/products_controller_decorator.rb index d185f4f85d..4f0c592284 100644 --- a/app/controllers/spree/admin/products_controller_decorator.rb +++ b/app/controllers/spree/admin/products_controller_decorator.rb @@ -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 diff --git a/app/controllers/spree/admin/reports_controller_decorator.rb b/app/controllers/spree/admin/reports_controller_decorator.rb index 62cfb585cd..377f1dbedf 100644 --- a/app/controllers/spree/admin/reports_controller_decorator.rb +++ b/app/controllers/spree/admin/reports_controller_decorator.rb @@ -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 }, diff --git a/app/controllers/spree/checkout_controller_decorator.rb b/app/controllers/spree/checkout_controller_decorator.rb index 66ca7fb034..5f6f7826e1 100644 --- a/app/controllers/spree/checkout_controller_decorator.rb +++ b/app/controllers/spree/checkout_controller_decorator.rb @@ -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) diff --git a/app/controllers/spree/paypal_controller_decorator.rb b/app/controllers/spree/paypal_controller_decorator.rb new file mode 100644 index 0000000000..fce09cfe0b --- /dev/null +++ b/app/controllers/spree/paypal_controller_decorator.rb @@ -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 diff --git a/app/helpers/admin/injection_helper.rb b/app/helpers/admin/injection_helper.rb new file mode 100644 index 0000000000..4bbff9bf79 --- /dev/null +++ b/app/helpers/admin/injection_helper.rb @@ -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 \ No newline at end of file diff --git a/app/helpers/checkout_helper.rb b/app/helpers/checkout_helper.rb index e5e721454a..5faccb781d 100644 --- a/app/helpers/checkout_helper.rb +++ b/app/helpers/checkout_helper.rb @@ -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 diff --git a/app/models/spree/product_decorator.rb b/app/models/spree/product_decorator.rb index 5894e46cc2..4faa54a06d 100644 --- a/app/models/spree/product_decorator.rb +++ b/app/models/spree/product_decorator.rb @@ -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, diff --git a/app/overrides/spree/admin/payment_methods/edit/add_new_payment_method_button.html.haml.deface b/app/overrides/spree/admin/payment_methods/edit/add_new_payment_method_button.html.haml.deface new file mode 100644 index 0000000000..fa595620e7 --- /dev/null +++ b/app/overrides/spree/admin/payment_methods/edit/add_new_payment_method_button.html.haml.deface @@ -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' %> \ No newline at end of file diff --git a/app/overrides/spree/admin/shipping_methods/edit/add_new_shipping_method_buttton.html.haml.deface b/app/overrides/spree/admin/shipping_methods/edit/add_new_shipping_method_buttton.html.haml.deface new file mode 100644 index 0000000000..b92e713258 --- /dev/null +++ b/app/overrides/spree/admin/shipping_methods/edit/add_new_shipping_method_buttton.html.haml.deface @@ -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' %> \ No newline at end of file diff --git a/app/serializers/api/admin/enterprise_serializer.rb b/app/serializers/api/admin/enterprise_serializer.rb new file mode 100644 index 0000000000..80acf6d7c4 --- /dev/null +++ b/app/serializers/api/admin/enterprise_serializer.rb @@ -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 \ No newline at end of file diff --git a/app/serializers/api/admin/id_name_serializer.rb b/app/serializers/api/admin/id_name_serializer.rb new file mode 100644 index 0000000000..1853aa46aa --- /dev/null +++ b/app/serializers/api/admin/id_name_serializer.rb @@ -0,0 +1,3 @@ +class Api::Admin::IdNameSerializer < ActiveModel::Serializer + attributes :id, :name +end \ No newline at end of file diff --git a/app/serializers/api/id_serializer.rb b/app/serializers/api/id_serializer.rb index 0093338e6e..bbd9b0ad56 100644 --- a/app/serializers/api/id_serializer.rb +++ b/app/serializers/api/id_serializer.rb @@ -1,3 +1,3 @@ class Api::IdSerializer < ActiveModel::Serializer attributes :id -end +end \ No newline at end of file diff --git a/app/views/admin/enterprises/_form.html.haml b/app/views/admin/enterprises/_form.html.haml index bc4d119e4d..e21e653a05 100644 --- a/app/views/admin/enterprises/_form.html.haml +++ b/app/views/admin/enterprises/_form.html.haml @@ -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 diff --git a/app/views/admin/enterprises/_ng_form.html.haml b/app/views/admin/enterprises/_ng_form.html.haml new file mode 100644 index 0000000000..7a4ec13a1f --- /dev/null +++ b/app/views/admin/enterprises/_ng_form.html.haml @@ -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 } \ No newline at end of file diff --git a/app/views/admin/enterprises/_sidebar.html.haml b/app/views/admin/enterprises/_sidebar.html.haml index 0390cb289a..7bd228c4c7 100644 --- a/app/views/admin/enterprises/_sidebar.html.haml +++ b/app/views/admin/enterprises/_sidebar.html.haml @@ -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}" } diff --git a/app/views/admin/enterprises/edit.html.haml b/app/views/admin/enterprises/edit.html.haml index f0f9c91fd1..38747a3252 100644 --- a/app/views/admin/enterprises/edit.html.haml +++ b/app/views/admin/enterprises/edit.html.haml @@ -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' diff --git a/app/views/admin/enterprises/new.html.haml b/app/views/admin/enterprises/new.html.haml index 9293cd3530..32f6ea0a8d 100644 --- a/app/views/admin/enterprises/new.html.haml +++ b/app/views/admin/enterprises/new.html.haml @@ -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' diff --git a/app/views/admin/json/_injection_ams.html.haml b/app/views/admin/json/_injection_ams.html.haml new file mode 100644 index 0000000000..50a22fa4ce --- /dev/null +++ b/app/views/admin/json/_injection_ams.html.haml @@ -0,0 +1,2 @@ +:javascript + angular.module("#{ngModule}").value("#{name.to_s}", #{json}) \ No newline at end of file diff --git a/app/views/checkout/_shipping.html.haml b/app/views/checkout/_shipping.html.haml index 67c24cf3c5..7906824a36 100644 --- a/app/views/checkout/_shipping.html.haml +++ b/app/views/checkout/_shipping.html.haml @@ -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 diff --git a/app/views/spree/admin/products/_primary_taxon_form.html.haml b/app/views/spree/admin/products/_primary_taxon_form.html.haml index 3cd7bdc931..23b2a0c8f3 100644 --- a/app/views/spree/admin/products/_primary_taxon_form.html.haml +++ b/app/views/spree/admin/products/_primary_taxon_form.html.haml @@ -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 diff --git a/app/views/spree/admin/shared/_hubs_sidebar.html.haml b/app/views/spree/admin/shared/_hubs_sidebar.html.haml index 4fe9b1078a..445a45ea6c 100644 --- a/app/views/spree/admin/shared/_hubs_sidebar.html.haml +++ b/app/views/spree/admin/shared/_hubs_sidebar.html.haml @@ -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 diff --git a/app/views/spree/checkout/payment/_paypalexpress.html.haml b/app/views/spree/checkout/payment/_paypal.html.haml similarity index 100% rename from app/views/spree/checkout/payment/_paypalexpress.html.haml rename to app/views/spree/checkout/payment/_paypal.html.haml diff --git a/app/views/spree/order_mailer/confirm_email.text.erb b/app/views/spree/order_mailer/confirm_email.text.erb index d5d07f0e90..a72ada83e2 100644 --- a/app/views/spree/order_mailer/confirm_email.text.erb +++ b/app/views/spree/order_mailer/confirm_email.text.erb @@ -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. diff --git a/config/ng-test.conf.js b/config/ng-test.conf.js index 1887ad7903..33f95483cf 100644 --- a/config/ng-test.conf.js +++ b/config/ng-test.conf.js @@ -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*', diff --git a/db/migrate/20140723021730_create_spree_paypal_express_checkouts.spree_paypal_express.rb b/db/migrate/20140723021730_create_spree_paypal_express_checkouts.spree_paypal_express.rb new file mode 100644 index 0000000000..1f30b68bff --- /dev/null +++ b/db/migrate/20140723021730_create_spree_paypal_express_checkouts.spree_paypal_express.rb @@ -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 diff --git a/db/migrate/20140723021731_add_transaction_id_to_spree_paypal_express_checkouts.spree_paypal_express.rb b/db/migrate/20140723021731_add_transaction_id_to_spree_paypal_express_checkouts.spree_paypal_express.rb new file mode 100644 index 0000000000..3603e8887a --- /dev/null +++ b/db/migrate/20140723021731_add_transaction_id_to_spree_paypal_express_checkouts.spree_paypal_express.rb @@ -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 diff --git a/db/migrate/20140723021732_add_state_to_spree_paypal_express_checkouts.spree_paypal_express.rb b/db/migrate/20140723021732_add_state_to_spree_paypal_express_checkouts.spree_paypal_express.rb new file mode 100644 index 0000000000..56a35ae307 --- /dev/null +++ b/db/migrate/20140723021732_add_state_to_spree_paypal_express_checkouts.spree_paypal_express.rb @@ -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 diff --git a/db/migrate/20140723021733_add_refunded_fields_to_spree_paypal_express_checkouts.spree_paypal_express.rb b/db/migrate/20140723021733_add_refunded_fields_to_spree_paypal_express_checkouts.spree_paypal_express.rb new file mode 100644 index 0000000000..eb2d10e7f7 --- /dev/null +++ b/db/migrate/20140723021733_add_refunded_fields_to_spree_paypal_express_checkouts.spree_paypal_express.rb @@ -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 diff --git a/db/migrate/20140723023713_switch_paypal_methods.rb b/db/migrate/20140723023713_switch_paypal_methods.rb new file mode 100644 index 0000000000..5b5509cb94 --- /dev/null +++ b/db/migrate/20140723023713_switch_paypal_methods.rb @@ -0,0 +1,13 @@ +class SwitchPaypalMethods < ActiveRecord::Migration + def up + Spree::PaymentMethod.connection.execute < 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" diff --git a/lib/open_food_network/option_value_namer.rb b/lib/open_food_network/option_value_namer.rb index 2447b9fee3..101fae427c 100644 --- a/lib/open_food_network/option_value_namer.rb +++ b/lib/open_food_network/option_value_namer.rb @@ -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. diff --git a/script/disable_s3.rb b/script/disable_s3.rb deleted file mode 100644 index f59ff95285..0000000000 --- a/script/disable_s3.rb +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env ruby - -Spree::Config.use_s3 = false - diff --git a/script/mirror_db.sh b/script/mirror_db.sh index 90fc914264..608f20eb75 100755 --- a/script/mirror_db.sh +++ b/script/mirror_db.sh @@ -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 diff --git a/script/prepare_imported_db.rb b/script/prepare_imported_db.rb new file mode 100644 index 0000000000..c3a217e546 --- /dev/null +++ b/script/prepare_imported_db.rb @@ -0,0 +1,4 @@ +#!/usr/bin/env ruby + +Spree::Config.use_s3 = false +Spree::PaymentMethod.update_all environment: 'development' diff --git a/spec/controllers/checkout_controller_spec.rb b/spec/controllers/checkout_controller_spec.rb index e46b9688a2..86e9689aa2 100644 --- a/spec/controllers/checkout_controller_spec.rb +++ b/spec/controllers/checkout_controller_spec.rb @@ -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 diff --git a/spec/controllers/spree/paypal_controller_spec.rb b/spec/controllers/spree/paypal_controller_spec.rb new file mode 100644 index 0000000000..200f4a9ff1 --- /dev/null +++ b/spec/controllers/spree/paypal_controller_spec.rb @@ -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 diff --git a/spec/features/admin/enterprises_spec.rb b/spec/features/admin/enterprises_spec.rb index e481be4635..4d277972e5 100644 --- a/spec/features/admin/enterprises_spec.rb +++ b/spec/features/admin/enterprises_spec.rb @@ -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' diff --git a/spec/features/consumer/shopping/checkout_spec.rb b/spec/features/consumer/shopping/checkout_spec.rb index 7f0affeaad..9c5d56e8aa 100644 --- a/spec/features/consumer/shopping/checkout_spec.rb +++ b/spec/features/consumer/shopping/checkout_spec.rb @@ -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 diff --git a/spec/javascripts/unit/admin/enterprises/controllers/enterprise_controller_spec.js.coffee b/spec/javascripts/unit/admin/enterprises/controllers/enterprise_controller_spec.js.coffee new file mode 100644 index 0000000000..b1b019276b --- /dev/null +++ b/spec/javascripts/unit/admin/enterprises/controllers/enterprise_controller_spec.js.coffee @@ -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 \ No newline at end of file diff --git a/spec/javascripts/unit/admin/enterprises/services/enterprise_spec.js.coffee b/spec/javascripts/unit/admin/enterprises/services/enterprise_spec.js.coffee new file mode 100644 index 0000000000..ed2b9be3c3 --- /dev/null +++ b/spec/javascripts/unit/admin/enterprises/services/enterprise_spec.js.coffee @@ -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 \ No newline at end of file diff --git a/spec/javascripts/unit/admin/services/option_value_namer_spec.js.coffee b/spec/javascripts/unit/admin/services/option_value_namer_spec.js.coffee index f58061ae27..198a09a8b8 100644 --- a/spec/javascripts/unit/admin/services/option_value_namer_spec.js.coffee +++ b/spec/javascripts/unit/admin/services/option_value_namer_spec.js.coffee @@ -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 diff --git a/spec/javascripts/unit/admin/services/variant_unit_manager_spec.js.coffee b/spec/javascripts/unit/admin/services/variant_unit_manager_spec.js.coffee new file mode 100644 index 0000000000..ff70e2a1d1 --- /dev/null +++ b/spec/javascripts/unit/admin/services/variant_unit_manager_spec.js.coffee @@ -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"] + ] diff --git a/spec/javascripts/unit/bulk_order_management_spec.js.coffee b/spec/javascripts/unit/bulk_order_management_spec.js.coffee index 4a189c7563..80884b855d 100644 --- a/spec/javascripts/unit/bulk_order_management_spec.js.coffee +++ b/spec/javascripts/unit/bulk_order_management_spec.js.coffee @@ -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 diff --git a/spec/lib/open_food_network/option_value_namer_spec.rb b/spec/lib/open_food_network/option_value_namer_spec.rb index c0758d2a37..b16574ba4c 100644 --- a/spec/lib/open_food_network/option_value_namer_spec.rb +++ b/spec/lib/open_food_network/option_value_namer_spec.rb @@ -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 \ No newline at end of file +end diff --git a/spec/serializers/admin/enterprise_serializer_spec.rb b/spec/serializers/admin/enterprise_serializer_spec.rb new file mode 100644 index 0000000000..bcaffcd291 --- /dev/null +++ b/spec/serializers/admin/enterprise_serializer_spec.rb @@ -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 \ No newline at end of file diff --git a/spec/serializers/enterprise_serializer.rb b/spec/serializers/enterprise_serializer_spec.rb similarity index 65% rename from spec/serializers/enterprise_serializer.rb rename to spec/serializers/enterprise_serializer_spec.rb index 263f621598..8072862e72 100644 --- a/spec/serializers/enterprise_serializer.rb +++ b/spec/serializers/enterprise_serializer_spec.rb @@ -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