Merge pull request #260 from openfoodfoundation/currency

Merge Currency branch
This commit is contained in:
rafaqz
2014-09-17 13:47:37 +10:00
22 changed files with 143 additions and 38 deletions

2
.gitignore vendored
View File

@@ -36,3 +36,5 @@ config/initializers/feature_toggle.rb
NERD_tree*
coverage
libpeerconnection.log
tags
app/assets/javascripts/tags

View File

@@ -0,0 +1,16 @@
# Convert number to string currency using injected currency configuration.
#
# @requires currencyConfig json - /app/serializers/api/currency_config_serializer.rb
# @return: string
Darkswarm.filter "localizeCurrency", (currencyConfig)->
(amount) ->
currency_code = if currencyConfig.display_currency then " " + currencyConfig.currency else ""
decimals = if currencyConfig.hide_cents == "true" then 0 else 2
# We need to use parseFloat before toFixed as the amount should be a passed in as a string.
amount_fixed = parseFloat(amount).toFixed(decimals)
# Build the final price string.
if currencyConfig.symbol_position == 'before'
currencyConfig.symbol + amount_fixed + currency_code
else
amount_fixed + " " + currencyConfig.symbol + currency_code

View File

@@ -3,7 +3,7 @@ Darkswarm.factory 'Cart', (CurrentOrder, Variants, $timeout, $http)->
new class Cart
dirty: false
order: CurrentOrder.order
line_items: CurrentOrder.order?.line_items || []
line_items: CurrentOrder.order?.line_items || []
constructor: ->
for line_item in @line_items
line_item.variant.line_item = line_item
@@ -22,13 +22,13 @@ Darkswarm.factory 'Cart', (CurrentOrder, Variants, $timeout, $http)->
# TODO what shall we do here?
data: =>
variants = {}
variants = {}
for li in @line_items_present()
variants[li.variant.id] =
variants[li.variant.id] =
quantity: li.quantity
max_quantity: li.max_quantity
{variants: variants}
saved: =>
@dirty = false
@@ -48,15 +48,15 @@ Darkswarm.factory 'Cart', (CurrentOrder, Variants, $timeout, $http)->
total: =>
@line_items_present().map (li)->
li.variant.getPrice()
li.variant.totalPrice()
.reduce (t, price)->
t + price
, 0
register_variant: (variant)=>
exists = @line_items.some (li)-> li.variant == variant
@create_line_item(variant) unless exists
@create_line_item(variant) unless exists
create_line_item: (variant)->
variant.line_item =
variant: variant

View File

@@ -5,7 +5,7 @@ Darkswarm.factory 'Variants', ->
@variants[variant.id] ||= @extend variant
extend: (variant)->
variant.getPrice = ->
variant.price * variant.line_item.quantity
variant.basePricePercentage = Math.round(variant.base_price / variant.price * 100)
variant.totalPrice = ->
variant.price_with_fees * variant.line_item.quantity
variant.basePricePercentage = Math.round(variant.price / variant.price_with_fees * 100)
variant

View File

@@ -10,26 +10,26 @@
.expanded{"ng-show" => "expanded"}
%ul
%li.cost
.right {{ variant.base_price | currency }}
.right {{ variant.price | localizeCurrency }}
Item cost
%li{"bo-if" => "variant.fees.admin"}
.right {{ variant.fees.admin | currency }}
.right {{ variant.fees.admin | localizeCurrency }}
Admin fee
%li{"bo-if" => "variant.fees.sales"}
.right {{ variant.fees.sales | currency }}
.right {{ variant.fees.sales | localizeCurrency }}
Sales fee
%li{"bo-if" => "variant.fees.packing"}
.right {{ variant.fees.packing | currency }}
.right {{ variant.fees.packing | localizeCurrency }}
Packing fee
%li{"bo-if" => "variant.fees.transport"}
.right {{ variant.fees.transport | currency }}
.right {{ variant.fees.transport | localizeCurrency }}
Transport fee
%li{"bo-if" => "variant.fees.fundraising"}
.right {{ variant.fees.fundraising | currency }}
.right {{ variant.fees.fundraising | localizeCurrency }}
Fundraising fee
%li
%strong
.right = {{ variant.price | currency }}
.right = {{ variant.price_with_fees | localizeCurrency }}
 
%a{"ng-click" => "expanded = !expanded"}

View File

@@ -48,7 +48,7 @@
.small-4.medium-2.large-2.columns.variant-price
.table-cell.price
%i.ofn-i_009-close
{{ variant.price | currency }}
{{ variant.price_with_fees | localizeCurrency }}
-# Now in a template in app/assets/javascripts/templates !
%price-breakdown{"price-breakdown" => "_", variant: "variant",
@@ -59,4 +59,4 @@
.small-12.medium-2.large-2.columns.total-price.text-right
.table-cell
%strong
{{ variant.getPrice() | currency }}
{{ variant.totalPrice() | localizeCurrency }}

View File

@@ -21,10 +21,14 @@ module InjectionHelper
inject_json_ams "taxons", Spree::Taxon.all, Api::TaxonSerializer
end
def inject_currency_config
inject_json_ams "currencyConfig", {}, Api::CurrencyConfigSerializer
end
def inject_spree_api_key
render partial: "json/injection_ams", locals: {name: 'spreeApiKey', json: "'#{@spree_api_key.to_s}'"}
end
def inject_available_countries
inject_json_ams "availableCountries", available_countries, Api::CountrySerializer
end

View File

@@ -8,7 +8,7 @@ module Spree
def order_distribution_subtotal(order, options={})
options.reverse_merge! :format_as_currency => true
amount = order.adjustments.enterprise_fee.sum &:amount
options.delete(:format_as_currency) ? number_to_currency(amount) : amount
options.delete(:format_as_currency) ? spree_number_to_currency(amount) : amount
end
def alternative_available_distributors(order)

View File

@@ -1,8 +1,9 @@
module Spree
ProductsHelper.class_eval do
# Return the price of the variant
# Return the price of the variant, overriding sprees price diff capability.
# This will allways return the variant price as if the show_variant_full_price is set.
def variant_price_diff(variant)
"(#{number_to_currency variant.price})"
"(#{Spree::Money.new(variant.price).to_s})"
end

View File

@@ -0,0 +1,5 @@
module SpreeCurrencyHelper
def spree_number_to_currency(amount)
Spree::Money.new(amount).to_s
end
end

View File

@@ -1,6 +1,7 @@
Spree::OrderMailer.class_eval do
helper HtmlHelper
helper CheckoutHelper
helper SpreeCurrencyHelper
def confirm_email(order, resend = false)
find_order(order)
subject = (resend ? "[#{t(:resend).upcase}] " : '')

View File

@@ -0,0 +1,32 @@
class Api::CurrencyConfigSerializer < ActiveModel::Serializer
attributes :currency, :display_currency, :symbol, :symbol_position, :hide_cents, :decimal_mark, :thousands_separator
def currency
Spree::Config[:currency]
end
def display_currency
Spree::Config[:display_currency]
end
def symbol
::Money.new(1, Spree::Config[:currency]).symbol
end
def symbol_position
Spree::Config[:currency_symbol_position]
end
def hide_cents
Spree::Config[:hide_cents]
end
def decimal_mark
Spree::Config[:currency_decimal_mark]
end
def thousands_separator
Spree::Config[:currency_thousands_separator]
end
end

View File

@@ -1,12 +1,12 @@
class Api::VariantSerializer < ActiveModel::Serializer
attributes :id, :is_master, :count_on_hand, :name_to_display, :unit_to_display,
:on_demand, :price, :fees, :base_price
:on_demand, :price, :fees, :price_with_fees
def price
def price_with_fees
object.price_with_fees(options[:current_distributor], options[:current_order_cycle])
end
def base_price
def price
object.price
end

View File

@@ -7,6 +7,7 @@ class Spree::Api::VariantSerializer < ActiveModel::Serializer
end
def price
# Decimals are passed to json as strings, we need to run parseFloat.toFixed(2) on the client side.
object.price.nil? ? 0.to_f : object.price
end
end
end

View File

@@ -5,7 +5,7 @@
%table
%tr
%th Cart total
%td.cart-total.text-right= number_to_currency checkout_cart_total_with_adjustments(current_order)
%td.cart-total.text-right= spree_number_to_currency(checkout_cart_total_with_adjustments(current_order))
- checkout_adjustments_for_summary(current_order, exclude: [:shipping, :distribution]).each do |adjustment|
%tr
@@ -14,11 +14,11 @@
%tr
%th Shipping
%td.shipping.text-right {{ Checkout.shippingPrice() | currency }}
%td.shipping.text-right {{ Checkout.shippingPrice() | localizeCurrency }}
%tr
%th Total
%td.total.text-right {{ Checkout.cartTotal() | currency }}
%td.total.text-right {{ Checkout.cartTotal() | localizeCurrency }}
- if current_order.price_adjustment_totals.present?
- current_order.price_adjustment_totals.each do |label, total|
%tr

View File

@@ -29,6 +29,7 @@
= inject_json "railsFlash", "flash"
= inject_taxons
= inject_current_order
= inject_currency_config
.off-canvas-wrap{offcanvas: true}
.inner-wrap

View File

@@ -22,20 +22,20 @@
%small
{{line_item.quantity}}
%i.ofn-i_009-close
{{ line_item.variant.price | currency }}
{{ line_item.variant.price_with_fees | localizeCurrency }}
.columns.small-2
%small
\=
%strong
.right {{ line_item.variant.getPrice() | currency }}
.right {{ line_item.variant.totalPrice() | localizeCurrency }}
%li.total-cart{"ng-show" => "Cart.line_items_present().length > 0"}
.row
.columns.small-6
%em Total:
.columns.small-6.text-right
%strong {{ Cart.total() | currency }}
%strong {{ Cart.total() | localizeCurrency }}
.text-right
%a.button.primary.small{href: checkout_path, "ng-disabled" => "Cart.dirty"} Quick checkout

View File

@@ -10,7 +10,7 @@ Order for: <%= @order.bill_address.full_name %>
<%= item.variant.sku %> <%= raw(item.variant.product.supplier.name) %> <%= raw(item.variant.product.name) %> <%= raw(item.variant.options_text) -%> (QTY: <%=item.quantity%>) @ <%= item.single_money %> = <%= item.display_amount %>
<% end %>
============================================================
Subtotal: <%= number_to_currency checkout_cart_total_with_adjustments(@order) %>
Subtotal: <%= spree_number_to_currency(checkout_cart_total_with_adjustments(@order)) %>
<% checkout_adjustments_for_summary(@order, exclude: [:distribution]).each do |adjustment| %>
<%= raw(adjustment.label) %> <%= adjustment.display_amount %>
<% end %>

View File

@@ -24,7 +24,7 @@
%td
Product
\:
%span.order-total.item-total= number_to_currency @order.item_total
%span.order-total.item-total= spree_number_to_currency(@order.item_total)
%td
Distribution
\:

View File

@@ -15,7 +15,7 @@
.product-image
= link_to small_image(product, :itemprop => "image"), product, :itemprop => 'url'
= link_to truncate(product.name, :length => 50), product, :class => 'info', :itemprop => "name", :title => product.name
%span.price.selling{:itemprop => "price"}= number_to_currency product.price
%span.price.selling{:itemprop => "price"}= spree_number_to_currency(product.price)
- if paginated_products.respond_to?(:num_pages)
- params.delete(:search)

View File

@@ -0,0 +1,42 @@
describe 'convert number to localised currency ', ->
filter = currencyconfig = null
beforeEach ->
currencyconfig =
symbol: "$"
symbol_position: "before"
currency: "D"
hide_cents: "false"
# Not used yet...
# decimal_mark: "."
# thousands_separator: ","
module 'Darkswarm'
module ($provide)->
$provide.value "currencyConfig", currencyconfig
null
inject ($filter) ->
filter = $filter('localizeCurrency')
it "adds decimal fraction to an amount", ->
expect(filter(10)).toEqual "$10.00"
it "handles an existing fraction", ->
expect(filter(9.9)).toEqual "$9.90"
it "can use any currency symbol", ->
currencyconfig.symbol = "£"
expect(filter(404.04)).toEqual "£404.04"
it "can place symbols after the amount", ->
currencyconfig.symbol_position = "after"
expect(filter(333.3)).toEqual "333.30 $"
it "can add a currency string", ->
currencyconfig.display_currency = "true"
expect(filter(5)).toEqual "$5.00 D"
it "can hide cents", ->
currencyconfig.hide_cents = "true"
expect(filter(5)).toEqual "$5"

View File

@@ -5,8 +5,8 @@ describe 'Variants service', ->
beforeEach ->
variant =
id: 1
base_price: 80.5
price: 100
price: 80.5
price_with_fees: 100
module 'Darkswarm'
inject ($injector)->
Variants = $injector.get("Variants")