diff --git a/.gitignore b/.gitignore index b587584d3b..f60933a3c1 100644 --- a/.gitignore +++ b/.gitignore @@ -36,3 +36,5 @@ config/initializers/feature_toggle.rb NERD_tree* coverage libpeerconnection.log +tags +app/assets/javascripts/tags diff --git a/app/assets/javascripts/darkswarm/filters/localize_currency.js.coffee b/app/assets/javascripts/darkswarm/filters/localize_currency.js.coffee new file mode 100644 index 0000000000..ffa98c5a33 --- /dev/null +++ b/app/assets/javascripts/darkswarm/filters/localize_currency.js.coffee @@ -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 diff --git a/app/assets/javascripts/darkswarm/services/cart.js.coffee b/app/assets/javascripts/darkswarm/services/cart.js.coffee index def1c9b6d0..2b58bb70ae 100644 --- a/app/assets/javascripts/darkswarm/services/cart.js.coffee +++ b/app/assets/javascripts/darkswarm/services/cart.js.coffee @@ -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 diff --git a/app/assets/javascripts/darkswarm/services/variants.js.coffee b/app/assets/javascripts/darkswarm/services/variants.js.coffee index 0f231ac030..bc2050e4d4 100644 --- a/app/assets/javascripts/darkswarm/services/variants.js.coffee +++ b/app/assets/javascripts/darkswarm/services/variants.js.coffee @@ -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 diff --git a/app/assets/javascripts/templates/price_breakdown.html.haml b/app/assets/javascripts/templates/price_breakdown.html.haml index 0b7eba917a..cf82e31457 100644 --- a/app/assets/javascripts/templates/price_breakdown.html.haml +++ b/app/assets/javascripts/templates/price_breakdown.html.haml @@ -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"} diff --git a/app/assets/javascripts/templates/shop_variant.html.haml b/app/assets/javascripts/templates/shop_variant.html.haml index a6db8b4e41..b1538bb69e 100644 --- a/app/assets/javascripts/templates/shop_variant.html.haml +++ b/app/assets/javascripts/templates/shop_variant.html.haml @@ -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 }} diff --git a/app/helpers/injection_helper.rb b/app/helpers/injection_helper.rb index 795dcb6a5c..046dd5d0eb 100644 --- a/app/helpers/injection_helper.rb +++ b/app/helpers/injection_helper.rb @@ -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 diff --git a/app/helpers/spree/orders_helper.rb b/app/helpers/spree/orders_helper.rb index b72fb43db5..93b59c8e4b 100644 --- a/app/helpers/spree/orders_helper.rb +++ b/app/helpers/spree/orders_helper.rb @@ -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) diff --git a/app/helpers/spree/products_helper_decorator.rb b/app/helpers/spree/products_helper_decorator.rb index f918a47649..22740218e1 100644 --- a/app/helpers/spree/products_helper_decorator.rb +++ b/app/helpers/spree/products_helper_decorator.rb @@ -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 diff --git a/app/helpers/spree_currency_helper.rb b/app/helpers/spree_currency_helper.rb new file mode 100644 index 0000000000..479ced2771 --- /dev/null +++ b/app/helpers/spree_currency_helper.rb @@ -0,0 +1,5 @@ +module SpreeCurrencyHelper + def spree_number_to_currency(amount) + Spree::Money.new(amount).to_s + end +end diff --git a/app/mailers/spree/order_mailer_decorator.rb b/app/mailers/spree/order_mailer_decorator.rb index cae4de0e79..a43399bd95 100644 --- a/app/mailers/spree/order_mailer_decorator.rb +++ b/app/mailers/spree/order_mailer_decorator.rb @@ -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}] " : '') diff --git a/app/serializers/api/currency_config_serializer.rb b/app/serializers/api/currency_config_serializer.rb new file mode 100644 index 0000000000..ab17af8715 --- /dev/null +++ b/app/serializers/api/currency_config_serializer.rb @@ -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 diff --git a/app/serializers/api/variant_serializer.rb b/app/serializers/api/variant_serializer.rb index e03f1e0ec8..5871d6def4 100644 --- a/app/serializers/api/variant_serializer.rb +++ b/app/serializers/api/variant_serializer.rb @@ -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 diff --git a/app/serializers/spree/api/variant_serializer.rb b/app/serializers/spree/api/variant_serializer.rb index f594a540ef..cd31196ca0 100644 --- a/app/serializers/spree/api/variant_serializer.rb +++ b/app/serializers/spree/api/variant_serializer.rb @@ -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 \ No newline at end of file +end diff --git a/app/views/checkout/_summary.html.haml b/app/views/checkout/_summary.html.haml index 0e03af7413..8609fd7a16 100644 --- a/app/views/checkout/_summary.html.haml +++ b/app/views/checkout/_summary.html.haml @@ -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 diff --git a/app/views/layouts/darkswarm.html.haml b/app/views/layouts/darkswarm.html.haml index 07b0db8dfa..0c6ec608d4 100644 --- a/app/views/layouts/darkswarm.html.haml +++ b/app/views/layouts/darkswarm.html.haml @@ -29,6 +29,7 @@ = inject_json "railsFlash", "flash" = inject_taxons = inject_current_order + = inject_currency_config .off-canvas-wrap{offcanvas: true} .inner-wrap diff --git a/app/views/shared/menu/_cart.html.haml b/app/views/shared/menu/_cart.html.haml index a61f80bf88..345365735b 100644 --- a/app/views/shared/menu/_cart.html.haml +++ b/app/views/shared/menu/_cart.html.haml @@ -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 diff --git a/app/views/spree/order_mailer/confirm_email.text.erb b/app/views/spree/order_mailer/confirm_email.text.erb index 932eaebe4c..a7ee445320 100644 --- a/app/views/spree/order_mailer/confirm_email.text.erb +++ b/app/views/spree/order_mailer/confirm_email.text.erb @@ -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 %> diff --git a/app/views/spree/orders/_form.html.haml b/app/views/spree/orders/_form.html.haml index 214823d4cf..953ea83e18 100644 --- a/app/views/spree/orders/_form.html.haml +++ b/app/views/spree/orders/_form.html.haml @@ -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 \: diff --git a/app/views/spree/shared/_products.html.haml b/app/views/spree/shared/_products.html.haml index bdb8b87600..8ea2743642 100644 --- a/app/views/spree/shared/_products.html.haml +++ b/app/views/spree/shared/_products.html.haml @@ -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) diff --git a/spec/javascripts/unit/darkswarm/filters/localize_currency_spec.js.coffee b/spec/javascripts/unit/darkswarm/filters/localize_currency_spec.js.coffee new file mode 100644 index 0000000000..0d21c7de6c --- /dev/null +++ b/spec/javascripts/unit/darkswarm/filters/localize_currency_spec.js.coffee @@ -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" + + diff --git a/spec/javascripts/unit/darkswarm/services/variants_spec.js.coffee b/spec/javascripts/unit/darkswarm/services/variants_spec.js.coffee index ac9865a142..5c6e138e0d 100644 --- a/spec/javascripts/unit/darkswarm/services/variants_spec.js.coffee +++ b/spec/javascripts/unit/darkswarm/services/variants_spec.js.coffee @@ -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")