mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-03-01 02:03:22 +00:00
Merge branch 'master' into line_item_naming
Conflicts: lib/open_food_network/order_cycle_management_report.rb lib/open_food_network/packing_report.rb
This commit is contained in:
@@ -1 +1 @@
|
||||
1.9.3-p392
|
||||
2.1.5
|
||||
|
||||
@@ -3,7 +3,7 @@ sudo: false
|
||||
cache: bundler
|
||||
bundler_args: --without development
|
||||
rvm:
|
||||
- "1.9.3"
|
||||
- "2.1.5"
|
||||
|
||||
# The test cases are roughly split according to their test times.
|
||||
# It would be better to use https://github.com/ArturT/knapsack.
|
||||
|
||||
4
Gemfile
4
Gemfile
@@ -1,5 +1,5 @@
|
||||
source 'https://rubygems.org'
|
||||
ruby "1.9.3"
|
||||
ruby "2.1.5"
|
||||
|
||||
gem 'rails', '3.2.21'
|
||||
gem 'rails-i18n', '~> 3.0.0'
|
||||
@@ -114,7 +114,7 @@ group :test do
|
||||
end
|
||||
|
||||
group :development do
|
||||
gem 'pry-debugger'
|
||||
gem 'pry-byebug'
|
||||
gem 'debugger-linecache'
|
||||
gem 'guard'
|
||||
gem 'guard-livereload'
|
||||
|
||||
22
Gemfile.lock
22
Gemfile.lock
@@ -171,6 +171,9 @@ GEM
|
||||
httparty (>= 0.6, < 1.0)
|
||||
multi_json (~> 1.0)
|
||||
builder (3.0.4)
|
||||
byebug (2.7.0)
|
||||
columnize (~> 0.3)
|
||||
debugger-linecache (~> 1.2)
|
||||
cancan (1.6.8)
|
||||
capybara (2.5.0)
|
||||
mime-types (>= 1.16)
|
||||
@@ -196,7 +199,7 @@ GEM
|
||||
execjs
|
||||
coffee-script-source (1.3.3)
|
||||
colorize (0.7.7)
|
||||
columnize (0.3.6)
|
||||
columnize (0.9.0)
|
||||
comfortable_mexican_sofa (1.6.24)
|
||||
active_link_to (~> 1.0.0)
|
||||
paperclip (>= 2.3.0)
|
||||
@@ -230,12 +233,7 @@ GEM
|
||||
activerecord (~> 3.0)
|
||||
fog (~> 1.0)
|
||||
rails (~> 3.0)
|
||||
debugger (1.6.1)
|
||||
columnize (>= 0.3.1)
|
||||
debugger-linecache (~> 1.2.0)
|
||||
debugger-ruby_core_source (~> 1.2.3)
|
||||
debugger-linecache (1.2.0)
|
||||
debugger-ruby_core_source (1.2.3)
|
||||
delayed_job (4.0.4)
|
||||
activesupport (>= 3.0, < 4.2)
|
||||
delayed_job_active_record (4.0.2)
|
||||
@@ -253,7 +251,7 @@ GEM
|
||||
eventmachine (>= 0.12.9)
|
||||
http_parser.rb (~> 0.5.3)
|
||||
erubis (2.7.0)
|
||||
eventmachine (1.0.3)
|
||||
eventmachine (1.0.8)
|
||||
excon (0.25.3)
|
||||
execjs (2.5.2)
|
||||
factory_girl (3.3.0)
|
||||
@@ -336,7 +334,7 @@ GEM
|
||||
addressable (~> 2.3)
|
||||
letter_opener (1.0.0)
|
||||
launchy (>= 2.0.4)
|
||||
libv8 (3.16.14.3)
|
||||
libv8 (3.16.14.11)
|
||||
listen (2.2.0)
|
||||
celluloid (>= 0.15.2)
|
||||
rb-fsevent (>= 0.9.3)
|
||||
@@ -391,9 +389,9 @@ GEM
|
||||
coderay (~> 1.0.5)
|
||||
method_source (~> 0.8)
|
||||
slop (~> 3.4)
|
||||
pry-debugger (0.2.2)
|
||||
debugger (~> 1.3)
|
||||
pry (~> 0.9.10)
|
||||
pry-byebug (1.3.2)
|
||||
byebug (~> 2.7)
|
||||
pry (~> 0.9.12)
|
||||
rabl (0.7.2)
|
||||
activesupport (>= 2.3.14)
|
||||
multi_json (~> 1.0)
|
||||
@@ -602,7 +600,7 @@ DEPENDENCIES
|
||||
parallel_tests
|
||||
pg
|
||||
poltergeist
|
||||
pry-debugger
|
||||
pry-byebug
|
||||
rabl
|
||||
rack-livereload
|
||||
rack-ssl
|
||||
|
||||
@@ -20,7 +20,7 @@ Below are instructions for setting up a development environment for Open Food Ne
|
||||
## Dependencies
|
||||
|
||||
* Rails 3.2.x
|
||||
* Ruby 1.9.3
|
||||
* Ruby 2.1.5
|
||||
* PostgreSQL database
|
||||
* PhantomJS (for testing)
|
||||
* See Gemfile for a list of gems required
|
||||
@@ -44,7 +44,7 @@ You can download the source with the command:
|
||||
|
||||
For those new to Rails, the following tutorial will help get you up to speed with configuring a Rails environment: http://guides.rubyonrails.org/getting_started.html .
|
||||
|
||||
First, check your dependencies: Ensure that you have Ruby >= 1.9.3 installed:
|
||||
First, check your dependencies: Ensure that you have Ruby 2.1.5 installed:
|
||||
|
||||
ruby --version
|
||||
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
module Spree
|
||||
module Admin
|
||||
AdjustmentsController.class_eval do
|
||||
before_filter :set_included_tax, only: [:create, :update]
|
||||
before_filter :set_default_tax_rate, only: :edit
|
||||
|
||||
|
||||
private
|
||||
|
||||
# Choose a default tax rate to show on the edit form. The adjustment stores its included
|
||||
# tax in dollars, but doesn't store the source of the tax (ie. TaxRate that generated it).
|
||||
# We guess which tax rate here, choosing:
|
||||
# 1. A tax rate that will compute to the same amount as the existing tax
|
||||
# 2. If that's not present, the first tax rate that's valid for the current order
|
||||
# When we have to go with 2, we show an error message to ask the admin to check that the
|
||||
# correct tax is being applied.
|
||||
def set_default_tax_rate
|
||||
if @adjustment.included_tax > 0
|
||||
trs = TaxRate.match(@order)
|
||||
tr_yielding_matching_tax = trs.select { |tr| tr.compute_tax(@adjustment.amount) == @adjustment.included_tax }.first.andand.id
|
||||
tr_valid_for_order = TaxRate.match(@order).first.andand.id
|
||||
|
||||
@tax_rate_id = tr_yielding_matching_tax || tr_valid_for_order
|
||||
|
||||
if tr_yielding_matching_tax.nil?
|
||||
@adjustment.errors.add :tax_rate_id, "^Please check that the tax rate for this adjustment is correct."
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def set_included_tax
|
||||
if params[:tax_rate_id].present?
|
||||
tax_rate = TaxRate.find params[:tax_rate_id]
|
||||
amount = params[:adjustment][:amount].to_f
|
||||
params[:adjustment][:included_tax] = tax_rate.compute_tax amount
|
||||
|
||||
else
|
||||
params[:adjustment][:included_tax] = 0
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -77,14 +77,27 @@ Spree::Admin::ReportsController.class_eval do
|
||||
end
|
||||
|
||||
def order_cycle_management
|
||||
prepare_date_params params
|
||||
|
||||
# -- Prepare form options
|
||||
my_distributors = Enterprise.is_distributor.managed_by(spree_current_user)
|
||||
my_suppliers = Enterprise.is_primary_producer.managed_by(spree_current_user)
|
||||
|
||||
# My distributors and any distributors distributing products I supply
|
||||
@distributors = my_distributors | Enterprise.with_distributed_products_outer.merge(Spree::Product.in_any_supplier(my_suppliers))
|
||||
# My suppliers and any suppliers supplying products I distribute
|
||||
@suppliers = my_suppliers | my_distributors.map { |d| Spree::Product.in_distributor(d) }.flatten.map(&:supplier).uniq
|
||||
@order_cycles = OrderCycle.active_or_complete.accessible_by(spree_current_user).order('orders_close_at DESC')
|
||||
|
||||
@report_types = REPORT_TYPES[:order_cycle_management]
|
||||
@report_type = params[:report_type]
|
||||
|
||||
# -- Build Report with Order Grouper
|
||||
@report = OpenFoodNetwork::OrderCycleManagementReport.new spree_current_user, params
|
||||
@table = @report.table_items
|
||||
csv_file_name = "#{params[:report_type]}_#{timestamp}.csv"
|
||||
|
||||
@search = Spree::Order.complete.not_state(:canceled).managed_by(spree_current_user).search(params[:q])
|
||||
@orders = @search.result
|
||||
|
||||
render_report(@report.header, @report.table, params[:csv], "order_cycle_management_#{timestamp}.csv")
|
||||
render_report(@report.header, @table, params[:csv], "order_cycle_management_#{timestamp}.csv")
|
||||
end
|
||||
|
||||
def packing
|
||||
@@ -294,9 +307,10 @@ Spree::Admin::ReportsController.class_eval do
|
||||
:sales_total => { :name => "Sales Total", :description => "Sales Total For All Orders" },
|
||||
:users_and_enterprises => { :name => "Users & Enterprises", :description => "Enterprise Ownership & Status" },
|
||||
:order_cycle_management => {:name => "Order Cycle Management", :description => ''},
|
||||
:packing => {:name => "Packing Reports", :description => ''},
|
||||
:sales_tax => { :name => "Sales Tax", :description => "Sales Tax For Orders" },
|
||||
:xero_invoices => { :name => "Xero Invoices", :description => 'Invoices for import into Xero' }
|
||||
:xero_invoices => { :name => "Xero Invoices", :description => 'Invoices for import into Xero' },
|
||||
:packing => { :name => "Packing Reports", :description => '' },
|
||||
:sales_tax => { :name => "Sales Tax", :description => "Sales Tax For Orders" }
|
||||
}
|
||||
# Return only reports the user is authorized to view.
|
||||
reports.select { |action| can? action, :report }
|
||||
|
||||
@@ -5,11 +5,13 @@ module Spree
|
||||
# AdjustmentMetadata has no destroy logic itself.
|
||||
has_one :metadata, class_name: 'AdjustmentMetadata'
|
||||
|
||||
scope :enterprise_fee, where(originator_type: 'EnterpriseFee')
|
||||
scope :enterprise_fee, where(originator_type: 'EnterpriseFee')
|
||||
scope :billable_period, where(source_type: 'BillablePeriod')
|
||||
scope :included_tax, where(originator_type: 'Spree::TaxRate', adjustable_type: 'Spree::LineItem')
|
||||
scope :with_tax, where('spree_adjustments.included_tax > 0')
|
||||
scope :without_tax, where('spree_adjustments.included_tax = 0')
|
||||
scope :admin, where(source_type: nil, originator_type: nil)
|
||||
scope :included_tax, where(originator_type: 'Spree::TaxRate', adjustable_type: 'Spree::LineItem')
|
||||
|
||||
scope :with_tax, where('spree_adjustments.included_tax > 0')
|
||||
scope :without_tax, where('spree_adjustments.included_tax = 0')
|
||||
|
||||
attr_accessible :included_tax
|
||||
|
||||
@@ -22,6 +24,10 @@ module Spree
|
||||
update_attributes! included_tax: tax.round(2)
|
||||
end
|
||||
|
||||
def display_included_tax
|
||||
Spree::Money.new(included_tax, { :currency => currency })
|
||||
end
|
||||
|
||||
def has_tax?
|
||||
included_tax > 0
|
||||
end
|
||||
|
||||
@@ -1,20 +1,61 @@
|
||||
Spree::TaxRate.class_eval do
|
||||
class << self
|
||||
def match_with_sales_tax_registration(order)
|
||||
return [] if order.distributor && !order.distributor.charges_sales_tax
|
||||
match_without_sales_tax_registration(order)
|
||||
module Spree
|
||||
TaxRate.class_eval do
|
||||
class << self
|
||||
def match_with_sales_tax_registration(order)
|
||||
return [] if order.distributor && !order.distributor.charges_sales_tax
|
||||
match_without_sales_tax_registration(order)
|
||||
end
|
||||
alias_method_chain :match, :sales_tax_registration
|
||||
end
|
||||
alias_method_chain :match, :sales_tax_registration
|
||||
end
|
||||
|
||||
|
||||
def adjust_with_included_tax(order)
|
||||
adjust_without_included_tax(order)
|
||||
def adjust_with_included_tax(order)
|
||||
adjust_without_included_tax(order)
|
||||
|
||||
order.reload
|
||||
(order.adjustments.tax + order.price_adjustments).each do |a|
|
||||
a.set_absolute_included_tax! a.amount
|
||||
order.reload
|
||||
(order.adjustments.tax + order.price_adjustments).each do |a|
|
||||
a.set_absolute_included_tax! a.amount
|
||||
end
|
||||
end
|
||||
alias_method_chain :adjust, :included_tax
|
||||
|
||||
|
||||
# Manually apply a TaxRate to a particular amount. TaxRates normally compute against
|
||||
# LineItems or Orders, so we mock out a line item here to fit the interface
|
||||
# that our calculator (usually DefaultTax) expects.
|
||||
def compute_tax(amount)
|
||||
product = OpenStruct.new tax_category: tax_category
|
||||
line_item = LineItem.new quantity: 1
|
||||
line_item.define_singleton_method(:product) { product }
|
||||
line_item.define_singleton_method(:price) { amount }
|
||||
|
||||
# Tax on adjustments (represented by the included_tax field) is always inclusive of
|
||||
# tax. However, there's nothing to stop an admin from setting one up with a tax rate
|
||||
# that's marked as not inclusive of tax, and that would result in the DefaultTax
|
||||
# calculator generating a slightly incorrect value. Therefore, we treat the tax
|
||||
# rate as inclusive of tax for the calculations below, regardless of its original
|
||||
# setting.
|
||||
with_tax_included_in_price do
|
||||
calculator.compute line_item
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
private
|
||||
|
||||
def with_tax_included_in_price
|
||||
old_included_in_price = self.included_in_price
|
||||
|
||||
self.included_in_price = true
|
||||
calculator.calculable.included_in_price = true
|
||||
|
||||
result = yield
|
||||
|
||||
ensure
|
||||
self.included_in_price = old_included_in_price
|
||||
calculator.calculable.included_in_price = old_included_in_price
|
||||
|
||||
result
|
||||
end
|
||||
end
|
||||
alias_method_chain :adjust, :included_tax
|
||||
end
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
/ replace_contents "[data-hook='adjustment_row']"
|
||||
|
||||
%td.align-center.created_at= pretty_time(adjustment.created_at)
|
||||
%td.align-center.label= adjustment.label
|
||||
%td.align-center.amount= adjustment.display_amount.to_html
|
||||
%td.align-center.included-tax= adjustment.display_included_tax.to_html
|
||||
%td.actions
|
||||
= link_to_edit adjustment, no_text: true
|
||||
= link_to_delete adjustment, no_text: true
|
||||
@@ -0,0 +1,8 @@
|
||||
/ replace_contents "[data-hook='adjustmment_head']"
|
||||
|
||||
%tr
|
||||
%th= "#{t('spree.date')}/#{t('spree.time')}"
|
||||
%th= t(:description)
|
||||
%th= t(:amount)
|
||||
%th= t(:included_tax)
|
||||
%th.actions
|
||||
@@ -0,0 +1,6 @@
|
||||
/ replace_contents "[data-hook='admin_adjustment_form_fields']"
|
||||
|
||||
- if @adjustment.new_record?
|
||||
= render 'new_form', f: f
|
||||
- else
|
||||
= render 'edit_form', f: f
|
||||
@@ -1,2 +1,2 @@
|
||||
object OpenStruct.new(flash)
|
||||
object OpenStruct.new(flash.to_hash)
|
||||
attributes :info, :success, :error
|
||||
|
||||
25
app/views/spree/admin/adjustments/_edit_form.html.haml
Normal file
25
app/views/spree/admin/adjustments/_edit_form.html.haml
Normal file
@@ -0,0 +1,25 @@
|
||||
.row
|
||||
.alpha.four.columns
|
||||
= f.field_container :amount do
|
||||
= f.label :amount, raw(t(:amount) + content_tag(:span, " *", :class => "required"))
|
||||
= text_field :adjustment, :amount, :class => 'fullwidth'
|
||||
= f.error_message_on :amount
|
||||
|
||||
.four.columns
|
||||
= f.field_container :included_tax do
|
||||
= f.label :included_tax, t(:included_tax)
|
||||
= text_field :adjustment, :included_tax, disabled: true, class: 'fullwidth'
|
||||
= f.error_message_on :included_tax
|
||||
|
||||
.omega.four.columns
|
||||
= f.field_container :tax_rate_id do
|
||||
= f.label :tax_rate_id, t(:tax_rate)
|
||||
= select_tag :tax_rate_id, options_from_collection_for_select(Spree::TaxRate.all, :id, :name, @tax_rate_id), prompt: t(:remove_tax), class: 'select2 fullwidth'
|
||||
= f.error_message_on :tax_rate_id
|
||||
|
||||
.row
|
||||
.alpha.omega.twelve.columns
|
||||
= f.field_container :label do
|
||||
= f.label :label, raw(t(:description) + content_tag(:span, " *", :class => "required"))
|
||||
= text_field :adjustment, :label, :class => 'fullwidth'
|
||||
= f.error_message_on :label
|
||||
19
app/views/spree/admin/adjustments/_new_form.html.haml
Normal file
19
app/views/spree/admin/adjustments/_new_form.html.haml
Normal file
@@ -0,0 +1,19 @@
|
||||
.row
|
||||
.alpha.three.columns
|
||||
= f.field_container :amount do
|
||||
= f.label :amount, raw(t(:amount) + content_tag(:span, " *", :class => "required"))
|
||||
= text_field :adjustment, :amount, :class => 'fullwidth'
|
||||
= f.error_message_on :amount
|
||||
|
||||
.omega.three.columns
|
||||
= f.field_container :tax_rate_id do
|
||||
= f.label :tax_rate_id, t(:tax_rate)
|
||||
= select_tag :tax_rate_id, options_from_collection_for_select(Spree::TaxRate.all, :id, :name), prompt: t(:none), class: 'select2 fullwidth'
|
||||
= f.error_message_on :tax_rate_id
|
||||
|
||||
.row
|
||||
.alpha.omega.twelve.columns
|
||||
= f.field_container :label do
|
||||
= f.label :label, raw(t(:description) + content_tag(:span, " *", :class => "required"))
|
||||
= text_field :adjustment, :label, :class => 'fullwidth'
|
||||
= f.error_message_on :label
|
||||
@@ -1,47 +1,46 @@
|
||||
= form_tag spree.order_cycle_management_admin_reports_url do |f|
|
||||
%br
|
||||
= label_tag nil, "Order Cycle: "
|
||||
= select_tag(:order_cycle_id,
|
||||
options_for_select(report_order_cycle_options(@order_cycles), params[:order_cycle_id]),
|
||||
include_blank: true)
|
||||
%br
|
||||
%br
|
||||
= label_tag nil, "Payment Methods (hold Ctrl to select multiple payment methods)"
|
||||
%br
|
||||
= form_for @report.search, :url => spree.order_cycle_management_admin_reports_path do |f|
|
||||
= render 'date_range_form', f: f
|
||||
|
||||
= select_tag(:payment_method_name,
|
||||
options_for_select(report_payment_method_options(@orders), params[:payment_method_name]),
|
||||
multiple: true, include_blank: true, size: 10)
|
||||
%br
|
||||
%br
|
||||
= label_tag nil, "Shipping Method: "
|
||||
= select_tag(:shipping_method_name,
|
||||
options_for_select(report_shipping_method_options(@orders), params[:shipping_method_name]),
|
||||
include_blank: true)
|
||||
%br
|
||||
%br
|
||||
= label_tag nil, "Report Type: "
|
||||
= select_tag(:report_type, options_for_select(@report_types, @report_type))
|
||||
%br
|
||||
%br
|
||||
= check_box_tag :csv
|
||||
= label_tag :csv, "Download as csv"
|
||||
%br
|
||||
%br
|
||||
.row
|
||||
.alpha.two.columns= label_tag nil, "Hubs: "
|
||||
.omega.fourteen.columns= f.collection_select(:distributor_id_in, @distributors, :id, :name, {}, {class: "select2 fullwidth", multiple: true})
|
||||
|
||||
.row
|
||||
.alpha.two.columns= label_tag nil, "Order Cycles: "
|
||||
.omega.fourteen.columns
|
||||
= f.select(:order_cycle_id_in, report_order_cycle_options(@order_cycles), {selected: params[:q][:order_cycle_id_in]}, {class: "select2 fullwidth", multiple: true})
|
||||
|
||||
.row
|
||||
.alpha.two.columns= label_tag nil, "Payment Methods: "
|
||||
.omega.fourteen.columns= select_tag(:payment_method_in, options_for_select(report_payment_method_options(@report.orders), params[:payment_method_in]), {class: "select2 fullwidth", multiple: true})
|
||||
|
||||
.row
|
||||
.alpha.two.columns= label_tag nil, "Shipping Methods: "
|
||||
.omega.fourteen.columns= select_tag(:shipping_method_in, options_for_select(report_shipping_method_options(@report.orders), params[:shipping_method_in]), {class: "select2 fullwidth", multiple: true})
|
||||
|
||||
.row
|
||||
.alpha.two.columns= label_tag nil, "Report Type: "
|
||||
.omega.fourteen.columns= select_tag(:report_type, options_for_select(@report_types, @report_type))
|
||||
|
||||
.row
|
||||
= check_box_tag :csv
|
||||
= label_tag :csv, "Download as csv"
|
||||
|
||||
.row
|
||||
= button t(:search)
|
||||
|
||||
%br
|
||||
%br
|
||||
%table#listing_order_payment_methods.index
|
||||
%table#listing_ocm_orders.index
|
||||
%thead
|
||||
%tr{'data-hook' => "orders_header"}
|
||||
- @report.header.each do |heading|
|
||||
%th=heading
|
||||
%tbody
|
||||
- @report.table.each do |row|
|
||||
- @table.each do |row|
|
||||
%tr
|
||||
- row.each do |column|
|
||||
%td= column
|
||||
- if @report.table.empty?
|
||||
- if @table.empty?
|
||||
%tr
|
||||
%td{:colspan => "2"}= t(:none)
|
||||
|
||||
@@ -40,3 +40,5 @@ en:
|
||||
footer_about_url: "About URL"
|
||||
footer_tos_url: "Terms of Service URL"
|
||||
invoice: "Invoice"
|
||||
included_tax: "Included tax"
|
||||
remove_tax: "Remove tax"
|
||||
|
||||
@@ -35,43 +35,8 @@ module OpenFoodNetwork
|
||||
tax_rates = enterprise_fee.tax_category ? enterprise_fee.tax_category.tax_rates.match(order) : []
|
||||
|
||||
tax_rates.sum do |rate|
|
||||
compute_tax rate, adjustment.amount
|
||||
rate.compute_tax adjustment.amount
|
||||
end
|
||||
end
|
||||
|
||||
# Apply a TaxRate to a particular amount. TaxRates normally compute against
|
||||
# LineItems or Orders, so we mock out a line item here to fit the interface
|
||||
# that our calculator (usually DefaultTax) expects.
|
||||
def compute_tax(tax_rate, amount)
|
||||
product = OpenStruct.new tax_category: tax_rate.tax_category
|
||||
line_item = Spree::LineItem.new quantity: 1
|
||||
line_item.define_singleton_method(:product) { product }
|
||||
line_item.define_singleton_method(:price) { amount }
|
||||
|
||||
# The enterprise fee adjustments for which we're calculating tax are always inclusive of
|
||||
# tax. However, there's nothing to stop an admin from setting one up with a tax rate
|
||||
# that's marked as not inclusive of tax, and that would result in the DefaultTax
|
||||
# calculator generating a slightly incorrect value. Therefore, we treat the tax
|
||||
# rate as inclusive of tax for the calculations below, regardless of its original
|
||||
# setting.
|
||||
with_tax_included_in_price(tax_rate) do
|
||||
tax_rate.calculator.compute line_item
|
||||
end
|
||||
end
|
||||
|
||||
def with_tax_included_in_price(tax_rate)
|
||||
old_included_in_price = tax_rate.included_in_price
|
||||
|
||||
tax_rate.included_in_price = true
|
||||
tax_rate.calculator.calculable.included_in_price = true
|
||||
|
||||
result = yield
|
||||
|
||||
tax_rate.included_in_price = old_included_in_price
|
||||
tax_rate.calculator.calculable.included_in_price = old_included_in_price
|
||||
|
||||
result
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -16,7 +16,15 @@ module OpenFoodNetwork
|
||||
end
|
||||
end
|
||||
|
||||
def table
|
||||
def search
|
||||
Spree::Order.complete.where("spree_orders.state != ?", :canceled).distributed_by_user(@user).managed_by(@user).search(params[:q])
|
||||
end
|
||||
|
||||
def orders
|
||||
filter search.result
|
||||
end
|
||||
|
||||
def table_items
|
||||
if is_payment_methods?
|
||||
orders.map { |o| payment_method_row o }
|
||||
else
|
||||
@@ -24,15 +32,10 @@ module OpenFoodNetwork
|
||||
end
|
||||
end
|
||||
|
||||
def orders
|
||||
filter Spree::Order.managed_by(@user).distributed_by_user(@user).complete.where("spree_orders.state != ?", :canceled)
|
||||
def filter(search_result)
|
||||
filter_to_payment_method filter_to_shipping_method filter_to_order_cycle search_result
|
||||
end
|
||||
|
||||
def filter(orders)
|
||||
filter_to_order_cycle filter_to_payment_method filter_to_shipping_method orders
|
||||
end
|
||||
|
||||
|
||||
private
|
||||
|
||||
def payment_method_row(order)
|
||||
|
||||
@@ -75,7 +75,9 @@ module OpenFoodNetwork
|
||||
{ group_by: proc { |line_item| line_item.product },
|
||||
sort_by: proc { |product| product.name } },
|
||||
{ group_by: proc { |line_item| line_item.full_name },
|
||||
sort_by: proc { |full_name| full_name } } ]
|
||||
sort_by: proc { |full_name| full_name } },
|
||||
{ group_by: proc { |line_item| line_item.order.bill_address.lastname },
|
||||
sort_by: proc { |lastname| lastname } } ]
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -34,10 +34,7 @@ module OpenFoodNetwork
|
||||
rows = []
|
||||
|
||||
rows += line_item_detail_rows(order, invoice_number, opts)
|
||||
|
||||
if order.account_invoice?
|
||||
rows += adjustment_detail_rows(order, invoice_number, opts)
|
||||
end
|
||||
rows += adjustment_detail_rows(order, invoice_number, opts)
|
||||
|
||||
rows
|
||||
end
|
||||
@@ -60,13 +57,13 @@ module OpenFoodNetwork
|
||||
end
|
||||
|
||||
def adjustment_detail_rows(order, invoice_number, opts)
|
||||
account_invoice_adjustments(order).map do |adjustment|
|
||||
adjustments(order).map do |adjustment|
|
||||
adjustment_detail_row(adjustment, invoice_number, opts)
|
||||
end
|
||||
end
|
||||
|
||||
def adjustment_detail_row(adjustment, invoice_number, opts)
|
||||
row(adjustment.source.andand.account_invoice.andand.order,
|
||||
row(adjustment_order(adjustment),
|
||||
'',
|
||||
adjustment.label,
|
||||
1,
|
||||
@@ -82,6 +79,7 @@ module OpenFoodNetwork
|
||||
rows += produce_summary_rows(order, invoice_number, opts) unless detail?
|
||||
rows += fee_summary_rows(order, invoice_number, opts) unless detail? && order.account_invoice?
|
||||
rows += shipping_summary_rows(order, invoice_number, opts)
|
||||
rows += admin_adjustment_summary_rows(order, invoice_number, opts) unless detail?
|
||||
|
||||
rows
|
||||
end
|
||||
@@ -100,6 +98,11 @@ module OpenFoodNetwork
|
||||
[summary_row(order, 'Delivery Shipping Cost (tax inclusive)', total_shipping(order), invoice_number, tax_on_shipping_s(order), opts)]
|
||||
end
|
||||
|
||||
def admin_adjustment_summary_rows(order, invoice_number, opts)
|
||||
[summary_row(order, 'Total untaxable admin adjustments (no tax)', total_untaxable_admin_adjustments(order), invoice_number, 'GST Free Income', opts),
|
||||
summary_row(order, 'Total taxable admin adjustments (tax inclusive)', total_taxable_admin_adjustments(order), invoice_number, 'GST on Income', opts)]
|
||||
end
|
||||
|
||||
def summary_row(order, description, amount, invoice_number, tax_type, opts={})
|
||||
row order, '', description, '1', amount, invoice_number, tax_type, opts
|
||||
end
|
||||
@@ -138,12 +141,21 @@ module OpenFoodNetwork
|
||||
]
|
||||
end
|
||||
|
||||
def adjustments(order)
|
||||
account_invoice_adjustments(order) + order.adjustments.admin
|
||||
end
|
||||
|
||||
def account_invoice_adjustments(order)
|
||||
order.adjustments.
|
||||
billable_period.
|
||||
select { |a| a.source.present? }
|
||||
end
|
||||
|
||||
def adjustment_order(adjustment)
|
||||
adjustment.source.andand.account_invoice.andand.order ||
|
||||
(adjustment.adjustable.is_a?(Spree::Order) ? adjustment.adjustable : nil)
|
||||
end
|
||||
|
||||
def invoice_number_for(order, i)
|
||||
@opts[:initial_invoice_number] ? @opts[:initial_invoice_number].to_i+i : order.number
|
||||
end
|
||||
@@ -173,6 +185,14 @@ module OpenFoodNetwork
|
||||
tax_on_shipping ? 'GST on Income' : 'GST Free Income'
|
||||
end
|
||||
|
||||
def total_untaxable_admin_adjustments(order)
|
||||
order.adjustments.admin.without_tax.sum &:amount
|
||||
end
|
||||
|
||||
def total_taxable_admin_adjustments(order)
|
||||
order.adjustments.admin.with_tax.sum &:amount
|
||||
end
|
||||
|
||||
def detail?
|
||||
@opts[:report_type] == 'detailed'
|
||||
end
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
function load_environment {
|
||||
source /var/lib/jenkins/.rvm/environments/ruby-1.9.3-p392
|
||||
source /var/lib/jenkins/.rvm/environments/ruby-2.1.5
|
||||
if [ ! -f config/application.yml ]; then
|
||||
ln -s application.yml.example config/application.yml
|
||||
fi
|
||||
|
||||
60
spec/controllers/spree/admin/adjustments_controller_spec.rb
Normal file
60
spec/controllers/spree/admin/adjustments_controller_spec.rb
Normal file
@@ -0,0 +1,60 @@
|
||||
require 'spec_helper'
|
||||
|
||||
module Spree
|
||||
describe Admin::AdjustmentsController do
|
||||
include AuthenticationWorkflow
|
||||
|
||||
before { login_as_admin }
|
||||
|
||||
describe "setting included tax" do
|
||||
let(:order) { create(:order) }
|
||||
let(:tax_rate) { create(:tax_rate, amount: 0.1, calculator: Spree::Calculator::DefaultTax.new) }
|
||||
|
||||
describe "creating an adjustment" do
|
||||
it "sets included tax to zero when no tax rate is specified" do
|
||||
spree_post :create, {order_id: order.number, adjustment: {label: 'Testing included tax', amount: '110'}, tax_rate_id: ''}
|
||||
response.should redirect_to spree.admin_order_adjustments_path(order)
|
||||
|
||||
a = Adjustment.last
|
||||
a.label.should == 'Testing included tax'
|
||||
a.amount.should == 110
|
||||
a.included_tax.should == 0
|
||||
end
|
||||
|
||||
it "calculates included tax when a tax rate is provided" do
|
||||
spree_post :create, {order_id: order.number, adjustment: {label: 'Testing included tax', amount: '110'}, tax_rate_id: tax_rate.id.to_s}
|
||||
response.should redirect_to spree.admin_order_adjustments_path(order)
|
||||
|
||||
a = Adjustment.last
|
||||
a.label.should == 'Testing included tax'
|
||||
a.amount.should == 110
|
||||
a.included_tax.should == 10
|
||||
end
|
||||
end
|
||||
|
||||
describe "updating an adjustment" do
|
||||
let(:adjustment) { create(:adjustment, adjustable: order, amount: 1100, included_tax: 100) }
|
||||
|
||||
it "sets included tax to zero when no tax rate is specified" do
|
||||
spree_put :update, {order_id: order.number, id: adjustment.id, adjustment: {label: 'Testing included tax', amount: '110'}, tax_rate_id: ''}
|
||||
response.should redirect_to spree.admin_order_adjustments_path(order)
|
||||
|
||||
a = Adjustment.last
|
||||
a.label.should == 'Testing included tax'
|
||||
a.amount.should == 110
|
||||
a.included_tax.should == 0
|
||||
end
|
||||
|
||||
it "calculates included tax when a tax rate is provided" do
|
||||
spree_put :update, {order_id: order.number, id: adjustment.id, adjustment: {label: 'Testing included tax', amount: '110'}, tax_rate_id: tax_rate.id.to_s}
|
||||
response.should redirect_to spree.admin_order_adjustments_path(order)
|
||||
|
||||
a = Adjustment.last
|
||||
a.label.should == 'Testing included tax'
|
||||
a.amount.should == 110
|
||||
a.included_tax.should == 10
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
89
spec/features/admin/adjustments_spec.rb
Normal file
89
spec/features/admin/adjustments_spec.rb
Normal file
@@ -0,0 +1,89 @@
|
||||
require "spec_helper"
|
||||
|
||||
feature %q{
|
||||
As an administrator
|
||||
I want to manage adjustments on orders
|
||||
} do
|
||||
include AuthenticationWorkflow
|
||||
include WebHelper
|
||||
|
||||
let!(:user) { create(:user) }
|
||||
let!(:distributor) { create(:distributor_enterprise, charges_sales_tax: true) }
|
||||
let!(:order_cycle) { create(:simple_order_cycle, distributors: [distributor]) }
|
||||
|
||||
let!(:order) { create(:order_with_totals_and_distribution, user: user, distributor: distributor, order_cycle: order_cycle, state: 'complete', payment_state: 'balance_due') }
|
||||
let!(:tax_rate) { create(:tax_rate, name: 'GST', calculator: build(:calculator, preferred_amount: 10), zone: create(:zone_with_member)) }
|
||||
|
||||
before do
|
||||
order.finalize!
|
||||
create(:check_payment, order: order, amount: order.total)
|
||||
end
|
||||
|
||||
scenario "adding taxed adjustments to an order" do
|
||||
# When I go to the adjustments page for the order
|
||||
login_to_admin_section
|
||||
visit spree.admin_orders_path
|
||||
page.find('td.actions a.icon-edit').click
|
||||
click_link 'Adjustments'
|
||||
|
||||
# And I create a new adjustment with tax
|
||||
click_link 'New Adjustment'
|
||||
fill_in 'adjustment_amount', with: 110
|
||||
fill_in 'adjustment_label', with: 'Late fee'
|
||||
select 'GST', from: 'tax_rate_id'
|
||||
click_button 'Continue'
|
||||
|
||||
# Then I should see the adjustment, with the correct tax
|
||||
page.should have_selector 'td.label', text: 'Late fee'
|
||||
page.should have_selector 'td.amount', text: '110'
|
||||
page.should have_selector 'td.included-tax', text: '10'
|
||||
end
|
||||
|
||||
scenario "modifying taxed adjustments on an order" do
|
||||
# Given a taxed adjustment
|
||||
adjustment = create(:adjustment, adjustable: order, amount: 110, included_tax: 10)
|
||||
|
||||
# When I go to the adjustments page for the order
|
||||
login_to_admin_section
|
||||
visit spree.admin_orders_path
|
||||
page.find('td.actions a.icon-edit').click
|
||||
click_link 'Adjustments'
|
||||
page.find('td.actions a.icon-edit').click
|
||||
|
||||
# Then I should see the uneditable included tax and our tax rate as the default
|
||||
page.should have_field :adjustment_included_tax, with: '10.00', disabled: true
|
||||
page.should have_select :tax_rate_id, selected: 'GST'
|
||||
|
||||
# When I edit the adjustment, removing the tax
|
||||
select 'Remove tax', from: :tax_rate_id
|
||||
click_button 'Continue'
|
||||
|
||||
# Then the adjustment tax should be cleared
|
||||
page.should have_selector 'td.amount', text: '110'
|
||||
page.should have_selector 'td.included-tax', text: '0'
|
||||
end
|
||||
|
||||
scenario "modifying an untaxed adjustment on an order" do
|
||||
# Given an untaxed adjustment
|
||||
adjustment = create(:adjustment, adjustable: order, amount: 110, included_tax: 0)
|
||||
|
||||
# When I go to the adjustments page for the order
|
||||
login_to_admin_section
|
||||
visit spree.admin_orders_path
|
||||
page.find('td.actions a.icon-edit').click
|
||||
click_link 'Adjustments'
|
||||
page.find('td.actions a.icon-edit').click
|
||||
|
||||
# Then I should see the uneditable included tax and 'Remove tax' as the default tax rate
|
||||
page.should have_field :adjustment_included_tax, with: '0.00', disabled: true
|
||||
page.should have_select :tax_rate_id, selected: []
|
||||
|
||||
# When I edit the adjustment, setting a tax rate
|
||||
select 'GST', from: :tax_rate_id
|
||||
click_button 'Continue'
|
||||
|
||||
# Then the adjustment tax should be recalculated
|
||||
page.should have_selector 'td.amount', text: '110'
|
||||
page.should have_selector 'td.included-tax', text: '10'
|
||||
end
|
||||
end
|
||||
@@ -289,7 +289,6 @@ feature %q{
|
||||
expect(page).to have_selector "tr#li_#{li1.id}"
|
||||
expect(page).to have_selector "tr#li_#{li2.id}"
|
||||
select2_select oc1.name, from: "order_cycle_filter"
|
||||
expect(page).to have_selector "#loading img.spinner"
|
||||
expect(page).to_not have_selector "#loading img.spinner"
|
||||
expect(page).to have_selector "tr#li_#{li1.id}"
|
||||
expect(page).to_not have_selector "tr#li_#{li2.id}"
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
require "spec_helper"
|
||||
|
||||
feature %q{
|
||||
As a payment administrator
|
||||
I want to capture multiple payments quickly from the one page
|
||||
As an administrator
|
||||
I want to manage orders
|
||||
} do
|
||||
include AuthenticationWorkflow
|
||||
include WebHelper
|
||||
@@ -10,7 +10,7 @@ feature %q{
|
||||
background do
|
||||
@user = create(:user)
|
||||
@product = create(:simple_product)
|
||||
@distributor = create(:distributor_enterprise)
|
||||
@distributor = create(:distributor_enterprise, charges_sales_tax: true)
|
||||
@order_cycle = create(:simple_order_cycle, distributors: [@distributor], variants: [@product.variants.first])
|
||||
|
||||
@order = create(:order_with_totals_and_distribution, user: @user, distributor: @distributor, order_cycle: @order_cycle, state: 'complete', payment_state: 'balance_due')
|
||||
@@ -106,6 +106,7 @@ feature %q{
|
||||
current_path.should == spree.admin_orders_path
|
||||
end
|
||||
|
||||
|
||||
context "as an enterprise manager" do
|
||||
let(:coordinator1) { create(:distributor_enterprise) }
|
||||
let(:coordinator2) { create(:distributor_enterprise) }
|
||||
|
||||
@@ -67,7 +67,7 @@ feature %q{
|
||||
|
||||
scenario "payment method report" do
|
||||
click_link "Payment Methods Report"
|
||||
rows = find("table#listing_order_payment_methods").all("thead tr")
|
||||
rows = find("table#listing_ocm_orders").all("thead tr")
|
||||
table = rows.map { |r| r.all("th").map { |c| c.text.strip } }
|
||||
table.sort.should == [
|
||||
["First Name", "Last Name", "Hub", "Hub Code", "Email", "Phone", "Shipping Method", "Payment Method", "Amount", "Balance"]
|
||||
@@ -76,7 +76,7 @@ feature %q{
|
||||
|
||||
scenario "delivery report" do
|
||||
click_link "Delivery Report"
|
||||
rows = find("table#listing_order_payment_methods").all("thead tr")
|
||||
rows = find("table#listing_ocm_orders").all("thead tr")
|
||||
table = rows.map { |r| r.all("th").map { |c| c.text.strip } }
|
||||
table.sort.should == [
|
||||
["First Name", "Last Name", "Hub", "Hub Code", "Delivery Address", "Delivery Postcode", "Phone", "Shipping Method", "Payment Method", "Amount", "Balance", "Temp Controlled Items?", "Special Instructions"]
|
||||
@@ -397,6 +397,8 @@ feature %q{
|
||||
let!(:adj_shipping) { create(:adjustment, adjustable: order1, label: "Shipping", originator: shipping_method, amount: 100.55, included_tax: 10.06) }
|
||||
let!(:adj_fee1) { create(:adjustment, adjustable: order1, originator: enterprise_fee1, label: "Enterprise fee untaxed", amount: 10, included_tax: 0) }
|
||||
let!(:adj_fee2) { create(:adjustment, adjustable: order1, originator: enterprise_fee2, label: "Enterprise fee taxed", amount: 20, included_tax: 2) }
|
||||
let!(:adj_manual1) { create(:adjustment, adjustable: order1, originator: nil, source: nil, label: "Manual adjustment", amount: 30, included_tax: 0) }
|
||||
let!(:adj_manual2) { create(:adjustment, adjustable: order1, originator: nil, source: nil, label: "Manual adjustment", amount: 40, included_tax: 3) }
|
||||
|
||||
|
||||
before do
|
||||
@@ -422,7 +424,9 @@ feature %q{
|
||||
xero_invoice_summary_row('Total taxable produce (tax inclusive)', 1500.45, 'GST on Income'),
|
||||
xero_invoice_summary_row('Total untaxable fees (no tax)', 10.0, 'GST Free Income'),
|
||||
xero_invoice_summary_row('Total taxable fees (tax inclusive)', 20.0, 'GST on Income'),
|
||||
xero_invoice_summary_row('Delivery Shipping Cost (tax inclusive)', 100.55, 'GST on Income')
|
||||
xero_invoice_summary_row('Delivery Shipping Cost (tax inclusive)', 100.55, 'GST on Income'),
|
||||
xero_invoice_summary_row('Total untaxable admin adjustments (no tax)', 30.0, 'GST Free Income'),
|
||||
xero_invoice_summary_row('Total taxable admin adjustments (tax inclusive)', 40.0, 'GST on Income')
|
||||
]
|
||||
end
|
||||
|
||||
@@ -441,7 +445,9 @@ feature %q{
|
||||
xero_invoice_summary_row('Total taxable produce (tax inclusive)', 1500.45, 'GST on Income', opts),
|
||||
xero_invoice_summary_row('Total untaxable fees (no tax)', 10.0, 'GST Free Income', opts),
|
||||
xero_invoice_summary_row('Total taxable fees (tax inclusive)', 20.0, 'GST on Income', opts),
|
||||
xero_invoice_summary_row('Delivery Shipping Cost (tax inclusive)', 100.55, 'GST on Income', opts)
|
||||
xero_invoice_summary_row('Delivery Shipping Cost (tax inclusive)', 100.55, 'GST on Income', opts),
|
||||
xero_invoice_summary_row('Total untaxable admin adjustments (no tax)', 30.0, 'GST Free Income', opts),
|
||||
xero_invoice_summary_row('Total taxable admin adjustments (tax inclusive)', 40.0, 'GST on Income', opts)
|
||||
]
|
||||
end
|
||||
|
||||
@@ -455,6 +461,8 @@ feature %q{
|
||||
xero_invoice_header,
|
||||
xero_invoice_li_row(line_item1),
|
||||
xero_invoice_li_row(line_item2),
|
||||
xero_invoice_adjustment_row(adj_manual1),
|
||||
xero_invoice_adjustment_row(adj_manual2),
|
||||
xero_invoice_summary_row('Total untaxable fees (no tax)', 10.0, 'GST Free Income', opts),
|
||||
xero_invoice_summary_row('Total taxable fees (tax inclusive)', 20.0, 'GST on Income', opts),
|
||||
xero_invoice_summary_row('Delivery Shipping Cost (tax inclusive)', 100.55, 'GST on Income', opts)
|
||||
@@ -511,12 +519,16 @@ feature %q{
|
||||
xero_invoice_row line_item.product.sku, line_item.variant.product_and_variant_name, line_item.price.to_s, line_item.quantity.to_s, tax_type, opts
|
||||
end
|
||||
|
||||
def xero_invoice_account_invoice_row(adjustment, opts={})
|
||||
opts.reverse_merge!({customer_name: '', address1: '', city: '', state: '', zipcode: '', country: '', invoice_number: account_invoice_order.number, order_number: account_invoice_order.number})
|
||||
def xero_invoice_adjustment_row(adjustment, opts={})
|
||||
tax_type = adjustment.has_tax? ? 'GST on Income' : 'GST Free Income'
|
||||
xero_invoice_row('', adjustment.label, adjustment.amount, '1', tax_type, opts)
|
||||
end
|
||||
|
||||
def xero_invoice_account_invoice_row(adjustment, opts={})
|
||||
opts.reverse_merge!({customer_name: '', address1: '', city: '', state: '', zipcode: '', country: '', invoice_number: account_invoice_order.number, order_number: account_invoice_order.number})
|
||||
xero_invoice_adjustment_row(adjustment, opts)
|
||||
end
|
||||
|
||||
def xero_invoice_row(sku, description, amount, quantity, tax_type, opts={})
|
||||
opts.reverse_merge!({customer_name: 'Customer Name', address1: 'customer l1', city: 'customer city', state: 'Victoria', zipcode: '1234', country: country.name, invoice_number: order1.number, order_number: order1.number, invoice_date: '2015-04-26', due_date: '2015-05-10', account_code: 'food sales'})
|
||||
|
||||
|
||||
@@ -65,33 +65,4 @@ module OpenFoodNetwork
|
||||
efa.send(:order_adjustment_label).should == "Whole order - packing fee by distributor Ballantyne"
|
||||
end
|
||||
end
|
||||
|
||||
describe "ensuring that tax rate is marked as tax included_in_price" do
|
||||
let(:efa) { EnterpriseFeeApplicator.new nil, nil, nil }
|
||||
let(:tax_rate) { create(:tax_rate, included_in_price: false, calculator: Spree::Calculator::DefaultTax.new) }
|
||||
|
||||
it "sets included_in_price to true" do
|
||||
efa.send(:with_tax_included_in_price, tax_rate) do
|
||||
tax_rate.included_in_price.should be_true
|
||||
end
|
||||
end
|
||||
|
||||
it "sets the included_in_price value accessible to the calculator to true" do
|
||||
efa.send(:with_tax_included_in_price, tax_rate) do
|
||||
tax_rate.calculator.calculable.included_in_price.should be_true
|
||||
end
|
||||
end
|
||||
|
||||
it "passes through the return value of the block" do
|
||||
efa.send(:with_tax_included_in_price, tax_rate) do
|
||||
'asdf'
|
||||
end.should == 'asdf'
|
||||
end
|
||||
|
||||
it "restores both values to their original afterwards" do
|
||||
efa.send(:with_tax_included_in_price, tax_rate) {}
|
||||
tax_rate.included_in_price.should be_false
|
||||
tax_rate.calculator.calculable.included_in_price.should be_false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -26,6 +26,7 @@ module OpenFoodNetwork
|
||||
report.stub(:produce_summary_rows) { ['produce'] }
|
||||
report.stub(:fee_summary_rows) { ['fee'] }
|
||||
report.stub(:shipping_summary_rows) { ['shipping'] }
|
||||
report.stub(:admin_adjustment_summary_rows) { ['admin'] }
|
||||
order.stub(:account_invoice?) { false }
|
||||
end
|
||||
|
||||
@@ -60,6 +61,15 @@ module OpenFoodNetwork
|
||||
it "always displays shipping summary rows" do
|
||||
summary_rows.should include 'shipping'
|
||||
end
|
||||
|
||||
it "displays admin adjustment summary rows when summary report" do
|
||||
summary_rows.should include 'admin'
|
||||
end
|
||||
|
||||
it "does not display admin adjustment summary rows when detail report" do
|
||||
report.stub(:detail?) { true }
|
||||
summary_rows.should_not include 'admin'
|
||||
end
|
||||
end
|
||||
|
||||
describe "finding account invoice adjustments" do
|
||||
|
||||
@@ -29,5 +29,42 @@ module Spree
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "ensuring that tax rate is marked as tax included_in_price" do
|
||||
let(:tax_rate) { create(:tax_rate, included_in_price: false, calculator: Spree::Calculator::DefaultTax.new) }
|
||||
|
||||
it "sets included_in_price to true" do
|
||||
tax_rate.send(:with_tax_included_in_price) do
|
||||
tax_rate.included_in_price.should be_true
|
||||
end
|
||||
end
|
||||
|
||||
it "sets the included_in_price value accessible to the calculator to true" do
|
||||
tax_rate.send(:with_tax_included_in_price) do
|
||||
tax_rate.calculator.calculable.included_in_price.should be_true
|
||||
end
|
||||
end
|
||||
|
||||
it "passes through the return value of the block" do
|
||||
tax_rate.send(:with_tax_included_in_price) do
|
||||
'asdf'
|
||||
end.should == 'asdf'
|
||||
end
|
||||
|
||||
it "restores both values to their original afterwards" do
|
||||
tax_rate.send(:with_tax_included_in_price) {}
|
||||
tax_rate.included_in_price.should be_false
|
||||
tax_rate.calculator.calculable.included_in_price.should be_false
|
||||
end
|
||||
|
||||
it "restores both values when an exception is raised" do
|
||||
expect do
|
||||
tax_rate.send(:with_tax_included_in_price) { raise Exception.new 'oops' }
|
||||
end.to raise_error 'oops'
|
||||
|
||||
tax_rate.included_in_price.should be_false
|
||||
tax_rate.calculator.calculable.included_in_price.should be_false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
module OpenFoodNetwork
|
||||
module HtmlHelper
|
||||
def save_and_open(html)
|
||||
def html_save_and_open(html)
|
||||
require "launchy"
|
||||
file = Tempfile.new('html')
|
||||
file.write html
|
||||
|
||||
Reference in New Issue
Block a user