mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-02-27 01:43:22 +00:00
Merge tag 'v1.8.10' into transifex
This commit is contained in:
@@ -1,3 +1,6 @@
|
||||
See this here post on raising a github issue:
|
||||
https://community.openfoodnetwork.org/t/how-to-raise-a-github-issue/912
|
||||
|
||||
# Contributing
|
||||
|
||||
We love pull requests from everyone. Here are some instructions for
|
||||
|
||||
@@ -643,9 +643,8 @@ GEM
|
||||
whenever (0.9.2)
|
||||
activesupport (>= 2.3.4)
|
||||
chronic (>= 0.6.3)
|
||||
wicked_pdf (0.11.0)
|
||||
rails
|
||||
wkhtmltopdf-binary (0.9.9.3)
|
||||
wicked_pdf (1.1.0)
|
||||
wkhtmltopdf-binary (0.12.3.1)
|
||||
xml-simple (1.1.4)
|
||||
xpath (2.0.0)
|
||||
nokogiri (~> 1.3)
|
||||
|
||||
@@ -98,6 +98,14 @@ The site is configured to use
|
||||
startup time while Rails loads. See the Zeus github page for
|
||||
usage instructions.
|
||||
|
||||
Once [npm dependencies are
|
||||
installed](https://github.com/openfoodfoundation/openfoodnetwork/wiki/Karma), AngularJS tests can be run with:
|
||||
|
||||
./script/karma run
|
||||
|
||||
If you want karma to automatically rerun the tests on file modification, use:
|
||||
|
||||
./script/karma start
|
||||
|
||||
## Credits
|
||||
|
||||
|
||||
@@ -12,7 +12,10 @@ angular.module('admin.orderCycles')
|
||||
$scope.StatusMessage = StatusMessage
|
||||
|
||||
$scope.$watch 'order_cycle_form.$dirty', (newValue) ->
|
||||
StatusMessage.display 'notice', 'You have unsaved changes' if newValue
|
||||
StatusMessage.display 'notice', t("admin.unsaved_changes") if newValue
|
||||
|
||||
$scope.$watch 'order_cycle_form.$valid', (isValid) ->
|
||||
StatusMessage.setValidation(isValid)
|
||||
|
||||
$scope.loaded = ->
|
||||
Enterprise.loaded && EnterpriseFee.loaded && OrderCycle.loaded
|
||||
|
||||
@@ -13,7 +13,10 @@ angular.module('admin.orderCycles')
|
||||
$scope.StatusMessage = StatusMessage
|
||||
|
||||
$scope.$watch 'order_cycle_form.$dirty', (newValue) ->
|
||||
StatusMessage.display 'notice', 'You have unsaved changes' if newValue
|
||||
StatusMessage.display 'notice', t("admin.unsaved_changes") if newValue
|
||||
|
||||
$scope.$watch 'order_cycle_form.$valid', (isValid) ->
|
||||
StatusMessage.setValidation(isValid)
|
||||
|
||||
$scope.loaded = ->
|
||||
Enterprise.loaded && EnterpriseFee.loaded && OrderCycle.loaded
|
||||
|
||||
@@ -8,7 +8,10 @@ angular.module('admin.orderCycles').controller "AdminSimpleCreateOrderCycleCtrl"
|
||||
$scope.enterprise_fees = EnterpriseFee.index(coordinator_id: ocInstance.coordinator_id)
|
||||
|
||||
$scope.$watch 'order_cycle_form.$dirty', (newValue) ->
|
||||
StatusMessage.display 'notice', 'You have unsaved changes' if newValue
|
||||
StatusMessage.display 'notice', t("admin.unsaved_changes") if newValue
|
||||
|
||||
$scope.$watch 'order_cycle_form.$valid', (isValid) ->
|
||||
StatusMessage.setValidation(isValid)
|
||||
|
||||
$scope.init = (enterprises) ->
|
||||
enterprise = enterprises[Object.keys(enterprises)[0]]
|
||||
|
||||
@@ -10,7 +10,10 @@ angular.module('admin.orderCycles').controller "AdminSimpleEditOrderCycleCtrl",
|
||||
$scope.init()
|
||||
|
||||
$scope.$watch 'order_cycle_form.$dirty', (newValue) ->
|
||||
StatusMessage.display 'notice', 'You have unsaved changes' if newValue
|
||||
StatusMessage.display 'notice', t("admin.unsaved_changes") if newValue
|
||||
|
||||
$scope.$watch 'order_cycle_form.$valid', (isValid) ->
|
||||
StatusMessage.setValidation(isValid)
|
||||
|
||||
$scope.loaded = ->
|
||||
Enterprise.loaded && EnterpriseFee.loaded && OrderCycle.loaded
|
||||
|
||||
@@ -11,6 +11,14 @@ angular.module("admin.utils").factory "StatusMessage", ($timeout) ->
|
||||
text: ""
|
||||
style: {}
|
||||
|
||||
invalidMessage: ""
|
||||
|
||||
setValidation: (isValid) ->
|
||||
if isValid
|
||||
StatusMessage.invalidMessage = ''
|
||||
else
|
||||
StatusMessage.invalidMessage = t("admin.form_invalid")
|
||||
|
||||
active: ->
|
||||
@statusMessage.text != ''
|
||||
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
#save-bar.animate-show{ ng: { show: 'dirty || persist || StatusMessage.active()' } }
|
||||
.container
|
||||
.eight.columns.alpha
|
||||
%h5#status-message{ ng: { style: 'StatusMessage.statusMessage.style' } }
|
||||
%h5#status-message{ ng: { show: "StatusMessage.invalidMessage == ''", style: 'StatusMessage.statusMessage.style' } }
|
||||
{{ StatusMessage.statusMessage.text || " " }}
|
||||
%h5#status-message{ ng: { show: "StatusMessage.invalidMessage !== ''" }, style: 'color: #da5354' }
|
||||
{{ StatusMessage.invalidMessage || " " }}
|
||||
.eight.columns.omega.text-right{ ng: { transclude: true } }
|
||||
|
||||
|
||||
@@ -74,6 +74,9 @@ form.order_cycle {
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
}
|
||||
.icon-question-sign {
|
||||
font-size: 18px;
|
||||
}
|
||||
table.exchanges {
|
||||
tr td.active {
|
||||
width: 20px;
|
||||
@@ -113,6 +116,14 @@ form.order_cycle {
|
||||
margin-right: 2em;
|
||||
}
|
||||
}
|
||||
.collection-details {
|
||||
input {
|
||||
width: 90%
|
||||
}
|
||||
span {
|
||||
font-size: 1rem
|
||||
}
|
||||
}
|
||||
}
|
||||
.coordinator-fees {
|
||||
margin-top: 1em;
|
||||
|
||||
@@ -23,6 +23,11 @@ class BaseController < ApplicationController
|
||||
private
|
||||
|
||||
def set_order_cycles
|
||||
unless @distributor.ready_for_checkout?
|
||||
@order_cycles = OrderCycle.where('false')
|
||||
return
|
||||
end
|
||||
|
||||
@order_cycles = OrderCycle.with_distributor(@distributor).active
|
||||
.order(@distributor.preferred_shopfront_order_cycle_order)
|
||||
|
||||
|
||||
@@ -54,12 +54,9 @@ module CheckoutHelper
|
||||
end
|
||||
|
||||
def display_adjustment_tax_rates(adjustment)
|
||||
tax_rate = (adjustment.included_tax / (adjustment.amount - adjustment.included_tax)).round(2)
|
||||
if tax_rate == 0 || tax_rate.infinite?
|
||||
""
|
||||
else
|
||||
number_to_percentage(tax_rate * 100, :precision => 1)
|
||||
end
|
||||
tax_rates = adjustment.tax_rates
|
||||
return "" if adjustment.amount == adjustment.included_tax
|
||||
tax_rates.map { |tr| number_to_percentage(tr.amount * 100, :precision => 1) }.join(", ")
|
||||
end
|
||||
|
||||
def display_adjustment_amount(adjustment)
|
||||
|
||||
@@ -34,10 +34,30 @@ module Spree
|
||||
included_tax > 0
|
||||
end
|
||||
|
||||
def display_included_tax
|
||||
Spree::Money.new(included_tax, { :currency => currency })
|
||||
def tax_rates
|
||||
case originator
|
||||
when Spree::TaxRate
|
||||
[originator]
|
||||
when EnterpriseFee
|
||||
case source
|
||||
when Spree::LineItem
|
||||
tax_category = originator.inherits_tax_category? ? source.product.tax_category : originator.tax_category
|
||||
return tax_category ? tax_category.tax_rates.match(source.order) : []
|
||||
when Spree::Order
|
||||
return originator.tax_category ? originator.tax_category.tax_rates.match(source) : []
|
||||
end
|
||||
else
|
||||
[find_closest_tax_rate_from_included_tax]
|
||||
end
|
||||
end
|
||||
|
||||
def find_closest_tax_rate_from_included_tax
|
||||
approximation = (included_tax / (amount - included_tax))
|
||||
return nil if approximation.infinite? or approximation.zero?
|
||||
Spree::TaxRate.order("ABS(amount - #{approximation})").first
|
||||
end
|
||||
|
||||
|
||||
def self.without_callbacks
|
||||
skip_callback :save, :after, :update_adjustable
|
||||
skip_callback :destroy, :after, :update_adjustable
|
||||
|
||||
@@ -234,12 +234,12 @@ Spree::Order.class_eval do
|
||||
|
||||
def tax_adjustment_totals
|
||||
tax_adjustments.each_with_object(Hash.new) do |adjustment, hash|
|
||||
if adjustment.originator_type == "Spree::TaxRate"
|
||||
tax_rate = adjustment.originator.amount
|
||||
else
|
||||
tax_rate = (adjustment.included_tax / (adjustment.amount - adjustment.included_tax)).round(2)
|
||||
end
|
||||
hash.update({tax_rate => adjustment.included_tax}) { |_tax_rate, amount1, amount2| amount1 + amount2 }
|
||||
tax_rates = adjustment.tax_rates
|
||||
tax_rates_hash = Hash[tax_rates.collect do |tax_rate|
|
||||
tax_amount = tax_rates.one? ? adjustment.included_tax : tax_rate.compute_tax(adjustment.amount)
|
||||
[tax_rate.amount, tax_amount]
|
||||
end]
|
||||
hash.update(tax_rates_hash) { |_tax_rate, amount1, amount2| amount1 + amount2 }
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -9,14 +9,16 @@
|
||||
selected
|
||||
- if type == 'supplier'
|
||||
%td.receival-details
|
||||
= text_field_tag 'order_cycle_incoming_exchange_{{ $index }}_receival_instructions', '', 'id' => 'order_cycle_incoming_exchange_{{ $index }}_receival_instructions', 'placeholder' => 'Receival instructions', 'ng-model' => 'exchange.receival_instructions'
|
||||
= text_field_tag 'order_cycle_incoming_exchange_{{ $index }}_receival_instructions', '', 'id' => 'order_cycle_incoming_exchange_{{ $index }}_receival_instructions', 'placeholder' => t('.receival_instructions_placeholder'), 'ng-model' => 'exchange.receival_instructions'
|
||||
- if type == 'distributor'
|
||||
%td.tags.panel-toggle.text-center{ name: "tags", ng: { if: 'enterprises[exchange.enterprise_id].managed || order_cycle.viewing_as_coordinator' } }
|
||||
{{ exchange.tags.length }}
|
||||
%td.collection-details
|
||||
= text_field_tag 'order_cycle_outgoing_exchange_{{ $index }}_pickup_time', '', 'id' => 'order_cycle_outgoing_exchange_{{ $index }}_pickup_time', 'placeholder' => 'Ready for (ie. Date / Time)', 'ng-model' => 'exchange.pickup_time', 'ng-disabled' => '!enterprises[exchange.enterprise_id].managed && !order_cycle.viewing_as_coordinator'
|
||||
= text_field_tag 'order_cycle_outgoing_exchange_{{ $index }}_pickup_time', '', 'id' => 'order_cycle_outgoing_exchange_{{ $index }}_pickup_time', 'required' => 'required', 'placeholder' => t('.pickup_time_placeholder'), 'ng-model' => 'exchange.pickup_time', 'ng-disabled' => '!enterprises[exchange.enterprise_id].managed && !order_cycle.viewing_as_coordinator', 'maxlength' => 35
|
||||
%span.icon-question-sign{'ofn-with-tip' => t('admin.order_cycles.edit.pickup_time_tip')}
|
||||
%br/
|
||||
= text_field_tag 'order_cycle_outgoing_exchange_{{ $index }}_pickup_instructions', '', 'id' => 'order_cycle_outgoing_exchange_{{ $index }}_pickup_instructions', 'placeholder' => 'Pick-up instructions', 'ng-model' => 'exchange.pickup_instructions', 'ng-disabled' => '!enterprises[exchange.enterprise_id].managed && !order_cycle.viewing_as_coordinator'
|
||||
= text_field_tag 'order_cycle_outgoing_exchange_{{ $index }}_pickup_instructions', '', 'id' => 'order_cycle_outgoing_exchange_{{ $index }}_pickup_instructions', 'placeholder' => t('.pickup_instructions_placeholder'), 'ng-model' => 'exchange.pickup_instructions', 'ng-disabled' => '!enterprises[exchange.enterprise_id].managed && !order_cycle.viewing_as_coordinator'
|
||||
%span.icon-question-sign{'ofn-with-tip' => t('admin.order_cycles.edit.pickup_instructions_tip')}
|
||||
%td.fees
|
||||
%ol{ ng: { show: 'enterprises[exchange.enterprise_id].managed || order_cycle.viewing_as_coordinator' } }
|
||||
%li{'ng-repeat' => 'enterprise_fee in exchange.enterprise_fees'}
|
||||
|
||||
@@ -4,11 +4,13 @@
|
||||
.alpha.two.columns
|
||||
= label_tag t('.ready_for')
|
||||
.six.columns
|
||||
= text_field_tag 'order_cycle_outgoing_exchange_0_pickup_time', '', 'id' => 'order_cycle_outgoing_exchange_0_pickup_time', 'placeholder' => t('.ready_for_placeholder'), 'ng-model' => 'outgoing_exchange.pickup_time', 'size' => 30
|
||||
= text_field_tag 'order_cycle_outgoing_exchange_0_pickup_time', '', 'id' => 'order_cycle_outgoing_exchange_0_pickup_time', 'required' => 'required', 'placeholder' => t('.ready_for_placeholder'), 'ng-model' => 'outgoing_exchange.pickup_time', 'size' => 30, 'maxlength' => 35
|
||||
%span.icon-question-sign{'ofn-with-tip' => t('admin.order_cycles.edit.pickup_time_tip')}
|
||||
.two.columns
|
||||
= label_tag t('.customer_instructions')
|
||||
.six.columns.omega
|
||||
= text_field_tag 'order_cycle_outgoing_exchange_0_pickup_instructions', '', 'id' => 'order_cycle_outgoing_exchange_0_pickup_instructions', 'placeholder' => t('.customer_instructions_placeholder'), 'ng-model' => 'outgoing_exchange.pickup_instructions', 'size' => 30
|
||||
%span.icon-question-sign{'ofn-with-tip' => t('admin.order_cycles.edit.pickup_instructions_tip')}
|
||||
|
||||
= label_tag t('.products')
|
||||
%table.exchanges
|
||||
|
||||
@@ -28,8 +28,8 @@
|
||||
= form_for [main_app, :admin, @order_cycle], :url => '', :html => {:class => 'ng order_cycle', 'ng-app' => 'admin.orderCycles', 'ng-controller' => ng_controller, name: 'order_cycle_form'} do |f|
|
||||
|
||||
%save-bar{ dirty: "order_cycle_form.$dirty", persist: "true" }
|
||||
%input.red{ type: "button", value: t(:update), ng: { click: "submit($event, null)", disabled: "!order_cycle_form.$dirty" } }
|
||||
%input.red{ type: "button", value: t('.update_and_close'), ng: { click: "submit($event, '#{main_app.admin_order_cycles_path}')", disabled: "!order_cycle_form.$dirty" } }
|
||||
%input.red{ type: "button", value: t(:update), ng: { click: "submit($event, null)", disabled: "!order_cycle_form.$dirty || order_cycle_form.$invalid" } }
|
||||
%input.red{ type: "button", value: t('.update_and_close'), ng: { click: "submit($event, '#{main_app.admin_order_cycles_path}')", disabled: "!order_cycle_form.$dirty || order_cycle_form.$invalid" } }
|
||||
%input{ type: "button", ng: { value: "order_cycle_form.$dirty ? 'Cancel' : 'Close'", click: "cancel('#{main_app.admin_order_cycles_path}')" } }
|
||||
|
||||
- if order_cycles_simple_form
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
= form_for [main_app, :admin, @order_cycle], :url => '', :html => {:class => 'ng order_cycle', 'ng-app' => 'admin.orderCycles', 'ng-controller' => ng_controller, name: 'order_cycle_form'} do |f|
|
||||
|
||||
%save-bar{ dirty: "order_cycle_form.$dirty", persist: "true" }
|
||||
%input.red{ type: "button", value: t(:create), ng: { click: "submit($event, '#{main_app.admin_order_cycles_path}')", disabled: "!order_cycle_form.$dirty" } }
|
||||
%input.red{ type: "button", value: t(:create), ng: { click: "submit($event, '#{main_app.admin_order_cycles_path}')", disabled: "!order_cycle_form.$dirty || order_cycle_form.$invalid" } }
|
||||
%input{ type: "button", ng: { value: "order_cycle_form.$dirty ? 'Cancel' : 'Close'", click: "cancel('#{main_app.admin_order_cycles_path}')" } }
|
||||
|
||||
- if order_cycles_simple_form
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
<%= t('.request_sent_text') %>
|
||||
|
||||
<%= t('.link_text') %>
|
||||
|
||||
<%= @edit_password_reset_url %>
|
||||
|
||||
<%= t('.issue_text') %>
|
||||
@@ -35,6 +35,7 @@ Openfoodnetwork::Application.configure do
|
||||
|
||||
# Tests assume English text on the site.
|
||||
config.i18n.default_locale = "en"
|
||||
I18n.locale = config.i18n.locale = config.i18n.default_locale
|
||||
|
||||
# Use SQL instead of Active Record's schema dumper when creating the test database.
|
||||
# This is necessary if your schema can't be completely dumped by the schema dumper,
|
||||
|
||||
@@ -70,6 +70,8 @@ en-GB:
|
||||
clear_all: Clear All
|
||||
start_date: "Start Date"
|
||||
end_date: "End Date"
|
||||
unsaved_changes: "You have unsaved changes"
|
||||
form_invalid: "Form contains missing or invalid fields"
|
||||
columns: Columns
|
||||
actions: Actions
|
||||
viewing: "Viewing: %{current_view_name}"
|
||||
@@ -198,7 +200,9 @@ en-GB:
|
||||
variants_without_unit_value: "WARNING: Some variants do not have a unit value"
|
||||
order_cycles:
|
||||
edit:
|
||||
choose_products_from: "Choose Products From:"
|
||||
choose_products_from: 'Choose Products From:'
|
||||
pickup_time_tip: When orders from this OC will be ready for the customer
|
||||
pickup_instructions_tip: These instructions are shown to customers after they complete an order
|
||||
enterprise:
|
||||
select_outgoing_oc_products_from: Select outgoing OC products from
|
||||
enterprises:
|
||||
|
||||
@@ -105,6 +105,8 @@ en:
|
||||
clear_all: Clear All
|
||||
start_date: "Start Date"
|
||||
end_date: "End Date"
|
||||
unsaved_changes: "You have unsaved changes"
|
||||
form_invalid: "Form contains missing or invalid fields"
|
||||
|
||||
columns: Columns
|
||||
actions: Actions
|
||||
@@ -275,10 +277,6 @@ en:
|
||||
order_error: "Some errors must be resolved before you can update orders.\nAny fields with red borders contain errors."
|
||||
variants_without_unit_value: "WARNING: Some variants do not have a unit value"
|
||||
|
||||
order_cycles:
|
||||
edit:
|
||||
choose_products_from: "Choose Products From:"
|
||||
|
||||
enterprise:
|
||||
select_outgoing_oc_products_from: Select outgoing OC products from
|
||||
|
||||
@@ -467,6 +465,16 @@ en:
|
||||
next_step: Next step
|
||||
choose_starting_point: 'Choose your starting point:'
|
||||
order_cycles:
|
||||
edit:
|
||||
advanced_settings: Advanced Settings
|
||||
update_and_close: Update and Close
|
||||
choose_products_from: 'Choose Products From:'
|
||||
pickup_time_tip: When orders from this OC will be ready for the customer
|
||||
pickup_instructions_tip: These instructions are shown to customers after they complete an order
|
||||
exchange_form:
|
||||
pickup_instructions_placeholder: "Pick-up instructions"
|
||||
pickup_time_placeholder: "Ready for (ie. Date / Time)"
|
||||
receival_instructions_placeholder: "Receival instructions"
|
||||
advanced_settings:
|
||||
title: Advanced Settings
|
||||
choose_product_tip: You can opt to restrict all available products (both incoming and outgoing), to only those in %{inventory}'s inventory.
|
||||
@@ -485,7 +493,7 @@ en:
|
||||
distributor: Distributor
|
||||
products: Products
|
||||
tags: Tags
|
||||
delivery_detaisl: Pickup / Delivery details
|
||||
delivery_details: Pickup / Delivery details
|
||||
debug_info: Debug information
|
||||
name_and_timing_form:
|
||||
name: Name
|
||||
@@ -503,9 +511,6 @@ en:
|
||||
customer_instructions_placeholder: Pick-up or delivery notes
|
||||
products: Products
|
||||
fees: Fees
|
||||
edit:
|
||||
advanced_settings: Advanced Settings
|
||||
update_and_close: Update and Close
|
||||
producer_properties:
|
||||
index:
|
||||
title: Producer Properties
|
||||
@@ -1591,3 +1596,13 @@ Please follow the instructions there to make your enterprise visible on the Open
|
||||
orders:
|
||||
invoice:
|
||||
tax_invoice: "TAX INVOICE: "
|
||||
user_mailer:
|
||||
reset_password_instructions:
|
||||
request_sent_text: |
|
||||
A request to reset your password has been made.
|
||||
If you did not make this request, simply ignore this email.
|
||||
link_text: >
|
||||
If you did make this request just click the link below:
|
||||
issue_text: |
|
||||
If the above URL does not work try copying and pasting it into your browser.
|
||||
If you continue to have problems please feel free to contact us.
|
||||
|
||||
@@ -32,21 +32,11 @@ module OpenFoodNetwork
|
||||
end
|
||||
|
||||
def adjustment_tax(adjustable, adjustment)
|
||||
tax_rates = rates_for(adjustable)
|
||||
tax_rates = adjustment.tax_rates
|
||||
|
||||
tax_rates.select(&:included_in_price).sum do |rate|
|
||||
rate.compute_tax adjustment.amount
|
||||
end
|
||||
end
|
||||
|
||||
def rates_for(adjustable)
|
||||
case adjustable
|
||||
when Spree::LineItem
|
||||
tax_category = enterprise_fee.inherits_tax_category? ? adjustable.product.tax_category : enterprise_fee.tax_category
|
||||
return tax_category ? tax_category.tax_rates.match(adjustable.order) : []
|
||||
when Spree::Order
|
||||
return enterprise_fee.tax_category ? enterprise_fee.tax_category.tax_rates.match(adjustable) : []
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
module OpenFoodNetwork
|
||||
class EnterpriseInjectionData
|
||||
def active_distributors
|
||||
@active_distributors ||= Enterprise.distributors_with_active_order_cycles
|
||||
@active_distributors ||= Enterprise.distributors_with_active_order_cycles.ready_for_checkout
|
||||
end
|
||||
|
||||
def earliest_closing_times
|
||||
|
||||
@@ -1,14 +1,22 @@
|
||||
namespace :karma do
|
||||
task :start => :environment do
|
||||
task :start => :environment do |task|
|
||||
continue_only_in_test_env task
|
||||
with_tmp_config :start
|
||||
end
|
||||
|
||||
task :run => :environment do
|
||||
task :run => :environment do |task|
|
||||
continue_only_in_test_env task
|
||||
with_tmp_config :start, "--single-run"
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def continue_only_in_test_env task
|
||||
if Rails.env != 'test'
|
||||
raise "Task must be called in test environment:\n bundle exec rake #{task.name} RAILS_ENV=test"
|
||||
end
|
||||
end
|
||||
|
||||
def with_tmp_config(command, args = nil)
|
||||
Tempfile.open('karma_unit.js', Rails.root.join('tmp') ) do |f|
|
||||
f.write unit_js(application_spec_files << i18n_file)
|
||||
|
||||
@@ -14,4 +14,4 @@ echo "--- Bundling"
|
||||
bundle install
|
||||
|
||||
echo "--- Running tests"
|
||||
bundle exec rake karma:run
|
||||
./script/karma run
|
||||
|
||||
13
script/karma
Executable file
13
script/karma
Executable file
@@ -0,0 +1,13 @@
|
||||
#!/bin/sh
|
||||
|
||||
task="$1"
|
||||
|
||||
if [ "$task" = "run" ] || [ "$task" = "start" ]; then
|
||||
exec bundle exec rake "karma:$task" RAILS_ENV=test
|
||||
else
|
||||
echo "Usage:"
|
||||
echo " $0 run # to run the tests once"
|
||||
echo " $0 start # to run the tests on every file modification"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe ShopController do
|
||||
let(:distributor) { create(:distributor_enterprise) }
|
||||
let!(:pm) { create(:payment_method) }
|
||||
let!(:sm) { create(:shipping_method) }
|
||||
let(:distributor) { create(:distributor_enterprise, payment_methods: [pm], shipping_methods: [sm]) }
|
||||
|
||||
it "redirects to the home page if no distributor is selected" do
|
||||
spree_get :show
|
||||
|
||||
@@ -6,7 +6,7 @@ describe ShopsController do
|
||||
let!(:invisible_distributor) { create(:distributor_enterprise, visible: false) }
|
||||
|
||||
before do
|
||||
Enterprise.stub(:distributors_with_active_order_cycles) { [distributor] }
|
||||
Enterprise.stub_chain("distributors_with_active_order_cycles.ready_for_checkout") { [distributor] }
|
||||
end
|
||||
|
||||
# Exclusion from actual rendered view handled in features/consumer/home
|
||||
|
||||
@@ -350,6 +350,8 @@ feature %q{
|
||||
fill_in 'order_cycle_outgoing_exchange_0_pickup_instructions', with: 'New instructions 0'
|
||||
fill_in 'order_cycle_outgoing_exchange_1_pickup_time', with: 'New time 1'
|
||||
fill_in 'order_cycle_outgoing_exchange_1_pickup_instructions', with: 'New instructions 1'
|
||||
fill_in 'order_cycle_outgoing_exchange_2_pickup_time', with: 'New time 2'
|
||||
fill_in 'order_cycle_outgoing_exchange_2_pickup_instructions', with: 'New instructions 2'
|
||||
|
||||
page.find("table.exchanges tr.distributor-#{distributor.id} td.tags").click
|
||||
within ".exchange-tags" do
|
||||
@@ -616,6 +618,11 @@ feature %q{
|
||||
select 'Permitted distributor', from: 'new_distributor_id'
|
||||
click_button 'Add distributor'
|
||||
|
||||
fill_in 'order_cycle_outgoing_exchange_0_pickup_time', with: 'pickup time'
|
||||
fill_in 'order_cycle_outgoing_exchange_0_pickup_instructions', with: 'pickup instructions'
|
||||
fill_in 'order_cycle_outgoing_exchange_1_pickup_time', with: 'pickup time 2'
|
||||
fill_in 'order_cycle_outgoing_exchange_1_pickup_instructions', with: 'pickup instructions'
|
||||
|
||||
# Should only have suppliers / distributors listed which the user is managing or
|
||||
# has E2E permission to add products to order cycles
|
||||
page.should_not have_select 'new_supplier_id', with_options: [supplier_unmanaged.name]
|
||||
|
||||
@@ -6,8 +6,8 @@ feature 'Shops', js: true do
|
||||
|
||||
let!(:distributor) { create(:distributor_enterprise, with_payment_and_shipping: true) }
|
||||
let!(:invisible_distributor) { create(:distributor_enterprise, visible: false) }
|
||||
let(:d1) { create(:distributor_enterprise) }
|
||||
let(:d2) { create(:distributor_enterprise) }
|
||||
let!(:d1) { create(:distributor_enterprise, with_payment_and_shipping: true) }
|
||||
let!(:d2) { create(:distributor_enterprise, with_payment_and_shipping: true) }
|
||||
let!(:order_cycle) { create(:simple_order_cycle, distributors: [distributor], coordinator: create(:distributor_enterprise)) }
|
||||
let!(:producer) { create(:supplier_enterprise) }
|
||||
let!(:er) { create(:enterprise_relationship, parent: distributor, child: producer) }
|
||||
@@ -57,6 +57,20 @@ feature 'Shops', js: true do
|
||||
end
|
||||
end
|
||||
|
||||
describe "showing available hubs" do
|
||||
let!(:hub) { create(:distributor_enterprise, with_payment_and_shipping: false) }
|
||||
let!(:order_cycle) { create(:simple_order_cycle, distributors: [hub], coordinator: hub) }
|
||||
let!(:producer) { create(:supplier_enterprise) }
|
||||
let!(:er) { create(:enterprise_relationship, parent: hub, child: producer) }
|
||||
|
||||
it "does not show hubs that are not ready for checkout" do
|
||||
visit shops_path
|
||||
|
||||
Enterprise.ready_for_checkout.should_not include hub
|
||||
page.should_not have_content hub.name
|
||||
end
|
||||
end
|
||||
|
||||
describe "filtering by product property" do
|
||||
let!(:order_cycle) { create(:simple_order_cycle, distributors: [d1, d2], coordinator: create(:distributor_enterprise)) }
|
||||
let!(:p1) { create(:simple_product, supplier: producer) }
|
||||
@@ -92,7 +106,7 @@ feature 'Shops', js: true do
|
||||
describe "taxon badges" do
|
||||
let!(:closed_oc) { create(:closed_order_cycle, distributors: [shop], variants: [p_closed.variants.first]) }
|
||||
let!(:p_closed) { create(:simple_product, taxons: [taxon_closed]) }
|
||||
let(:shop) { create(:distributor_enterprise) }
|
||||
let(:shop) { create(:distributor_enterprise, with_payment_and_shipping: true) }
|
||||
let(:taxon_closed) { create(:taxon, name: 'Closed') }
|
||||
|
||||
describe "open shops" do
|
||||
|
||||
@@ -2,7 +2,7 @@ require 'spec_helper'
|
||||
|
||||
describe Spree::UserMailer do
|
||||
let(:user) { build(:user) }
|
||||
|
||||
|
||||
after do
|
||||
ActionMailer::Base.deliveries.clear
|
||||
end
|
||||
@@ -17,4 +17,37 @@ describe Spree::UserMailer do
|
||||
Spree::UserMailer.signup_confirmation(user).deliver
|
||||
ActionMailer::Base.deliveries.count.should == 1
|
||||
end
|
||||
|
||||
# adapted from https://github.com/spree/spree_auth_devise/blob/70737af/spec/mailers/user_mailer_spec.rb
|
||||
describe '#reset_password_instructions' do
|
||||
describe 'message contents' do
|
||||
before do
|
||||
@message = described_class.reset_password_instructions(user)
|
||||
end
|
||||
|
||||
context 'subject includes' do
|
||||
it 'translated devise instructions' do
|
||||
expect(@message.subject).to include "Password Reset Instructions"
|
||||
end
|
||||
|
||||
it 'Spree site name' do
|
||||
expect(@message.subject).to include Spree::Config[:site_name]
|
||||
end
|
||||
end
|
||||
|
||||
context 'body includes' do
|
||||
it 'password reset url' do
|
||||
expect(@message.body.raw_source).to include root_url + "user/spree_user/password/edit"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'legacy support for User object' do
|
||||
it 'sends an email' do
|
||||
expect do
|
||||
Spree::UserMailer.reset_password_instructions(user).deliver
|
||||
end.to change(ActionMailer::Base.deliveries, :size).by(1)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
require 'spec_helper'
|
||||
|
||||
module Spree
|
||||
describe Adjustment do
|
||||
it "has metadata" do
|
||||
@@ -279,6 +281,21 @@ module Spree
|
||||
adjustment.included_tax.should == 10.00
|
||||
end
|
||||
end
|
||||
|
||||
describe "getting the corresponding tax rate" do
|
||||
let!(:adjustment_with_tax) { create(:adjustment, amount: 50, included_tax: 10) }
|
||||
let!(:adjustment_without_tax) { create(:adjustment, amount: 50, included_tax: 0) }
|
||||
let!(:tax_rate) { create(:tax_rate, calculator: Spree::Calculator::DefaultTax.new, amount: 0.25) }
|
||||
let!(:other_tax_rate) { create(:tax_rate, calculator: Spree::Calculator::DefaultTax.new, amount: 0.3) }
|
||||
|
||||
it "returns nil if there is no included tax" do
|
||||
adjustment_without_tax.find_closest_tax_rate_from_included_tax.should == nil
|
||||
end
|
||||
|
||||
it "returns the most accurate tax rate" do
|
||||
adjustment_with_tax.find_closest_tax_rate_from_included_tax.should == tax_rate
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -276,6 +276,50 @@ describe Spree::Order do
|
||||
end
|
||||
end
|
||||
|
||||
describe "getting a hash of all taxes" do
|
||||
let(:zone) { create(:zone_with_member) }
|
||||
let(:coordinator) { create(:distributor_enterprise, charges_sales_tax: true) }
|
||||
|
||||
let(:tax_rate10) { create(:tax_rate, included_in_price: true, calculator: Spree::Calculator::DefaultTax.new, amount: 0.1, zone: zone) }
|
||||
let(:tax_rate15) { create(:tax_rate, included_in_price: true, calculator: Spree::Calculator::DefaultTax.new, amount: 0.15, zone: zone) }
|
||||
let(:tax_rate20) { create(:tax_rate, included_in_price: true, calculator: Spree::Calculator::DefaultTax.new, amount: 0.2, zone: zone) }
|
||||
let(:tax_category10) { create(:tax_category, tax_rates: [tax_rate10]) }
|
||||
let(:tax_category15) { create(:tax_category, tax_rates: [tax_rate15]) }
|
||||
let(:tax_category20) { create(:tax_category, tax_rates: [tax_rate20]) }
|
||||
|
||||
let(:variant) { create(:variant, product: create(:product, tax_category: tax_category10)) }
|
||||
let(:shipping_method) { create(:shipping_method, calculator: Spree::Calculator::FlatRate.new(preferred_amount: 46.0)) }
|
||||
let(:enterprise_fee) { create(:enterprise_fee, enterprise: coordinator, tax_category: tax_category20, calculator: Spree::Calculator::FlatRate.new(preferred_amount: 48.0)) }
|
||||
|
||||
let(:order_cycle) { create(:simple_order_cycle, coordinator: coordinator, coordinator_fees: [enterprise_fee], distributors: [coordinator], variants: [variant]) }
|
||||
let!(:order) { create(:order, shipping_method: shipping_method, bill_address: create(:address), order_cycle: order_cycle, distributor: coordinator) }
|
||||
let!(:line_item) { create(:line_item, order: order, variant: variant, price: 44.0) }
|
||||
|
||||
before do
|
||||
Spree::Config.shipment_inc_vat = true
|
||||
Spree::Config.shipping_tax_rate = tax_rate15.amount
|
||||
order.create_shipment!
|
||||
Spree::TaxRate.adjust(order)
|
||||
order.reload.update_distribution_charge!
|
||||
end
|
||||
|
||||
it "returns a hash with all 3 taxes" do
|
||||
order.tax_adjustment_totals.size.should == 3
|
||||
end
|
||||
|
||||
it "contains tax on line_item" do
|
||||
order.tax_adjustment_totals[tax_rate10.amount].should == 4.0
|
||||
end
|
||||
|
||||
it "contains tax on shipping_fee" do
|
||||
order.tax_adjustment_totals[tax_rate15.amount].should == 6.0
|
||||
end
|
||||
|
||||
it "contains tax on enterprise_fee" do
|
||||
order.tax_adjustment_totals[tax_rate20.amount].should == 8.0
|
||||
end
|
||||
end
|
||||
|
||||
describe "setting the distributor" do
|
||||
it "sets the distributor when no order cycle is set" do
|
||||
d = create(:distributor_enterprise)
|
||||
|
||||
Reference in New Issue
Block a user