use ruby-units for unit parsing (closes foodcoops/foodsoft#200)
Conflicts: Gemfile Gemfile.lock
This commit is contained in:
parent
48e9a3e4f5
commit
c25d4d3f4f
5 changed files with 48 additions and 23 deletions
1
Gemfile
1
Gemfile
|
@ -39,6 +39,7 @@ gem "rails-settings-cached", "0.3.1"
|
||||||
gem 'resque'
|
gem 'resque'
|
||||||
gem 'whenever', require: false # For defining cronjobs, see config/schedule.rb
|
gem 'whenever', require: false # For defining cronjobs, see config/schedule.rb
|
||||||
gem 'protected_attributes'
|
gem 'protected_attributes'
|
||||||
|
gem 'ruby-units'
|
||||||
|
|
||||||
# we use the git version of acts_as_versioned, and need to include it in this Gemfile
|
# we use the git version of acts_as_versioned, and need to include it in this Gemfile
|
||||||
gem 'acts_as_versioned', git: 'git://github.com/technoweenie/acts_as_versioned.git'
|
gem 'acts_as_versioned', git: 'git://github.com/technoweenie/acts_as_versioned.git'
|
||||||
|
|
|
@ -281,6 +281,7 @@ GEM
|
||||||
rspec-rerun (0.1.3)
|
rspec-rerun (0.1.3)
|
||||||
rspec (>= 2.11.0)
|
rspec (>= 2.11.0)
|
||||||
ruby-prof (0.14.2)
|
ruby-prof (0.14.2)
|
||||||
|
ruby-units (1.4.4)
|
||||||
rubyzip (1.1.0)
|
rubyzip (1.1.0)
|
||||||
sass (3.2.14)
|
sass (3.2.14)
|
||||||
sass-rails (4.0.1)
|
sass-rails (4.0.1)
|
||||||
|
@ -421,6 +422,7 @@ DEPENDENCIES
|
||||||
rspec-rails
|
rspec-rails
|
||||||
rspec-rerun
|
rspec-rerun
|
||||||
ruby-prof
|
ruby-prof
|
||||||
|
ruby-units
|
||||||
sass-rails (~> 4.0.0)
|
sass-rails (~> 4.0.0)
|
||||||
select2-rails
|
select2-rails
|
||||||
selenium-webdriver
|
selenium-webdriver
|
||||||
|
|
|
@ -117,6 +117,7 @@ class Article < ActiveRecord::Base
|
||||||
# returns nil if units are eqal
|
# returns nil if units are eqal
|
||||||
def convert_units
|
def convert_units
|
||||||
if unit != shared_article.unit
|
if unit != shared_article.unit
|
||||||
|
# legacy, used by foodcoops in Germany
|
||||||
if shared_article.unit == "KI" and unit == "ST" # 'KI' means a box, with a different amount of items in it
|
if shared_article.unit == "KI" and unit == "ST" # 'KI' means a box, with a different amount of items in it
|
||||||
# try to match the size out of its name, e.g. "banana 10-12 St" => 10
|
# try to match the size out of its name, e.g. "banana 10-12 St" => 10
|
||||||
new_unit_quantity = /[0-9\-\s]+(St)/.match(shared_article.name).to_s.to_i
|
new_unit_quantity = /[0-9\-\s]+(St)/.match(shared_article.name).to_s.to_i
|
||||||
|
@ -126,13 +127,13 @@ class Article < ActiveRecord::Base
|
||||||
else
|
else
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
else # get factors for fc and supplier
|
else # use ruby-units to convert
|
||||||
fc_unit_factor = FoodsoftConfig[:units][self.unit]
|
fc_unit = (::Unit.new(unit) rescue nil)
|
||||||
supplier_unit_factor = FoodsoftConfig[:units][self.shared_article.unit]
|
supplier_unit = (::Unit.new(shared_article.unit) rescue nil)
|
||||||
if fc_unit_factor and supplier_unit_factor
|
if fc_unit and supplier_unit and fc_unit =~ supplier_unit
|
||||||
convertion_factor = fc_unit_factor / supplier_unit_factor
|
conversion_factor = (fc_unit.convert_to(supplier_unit.units) / supplier_unit).scalar
|
||||||
new_price = BigDecimal((convertion_factor * shared_article.price).to_s).round(2)
|
new_price = shared_article.price * conversion_factor
|
||||||
new_unit_quantity = ( 1 / convertion_factor) * shared_article.unit_quantity
|
new_unit_quantity = shared_article.unit_quantity / conversion_factor
|
||||||
[new_price, new_unit_quantity]
|
[new_price, new_unit_quantity]
|
||||||
else
|
else
|
||||||
false
|
false
|
||||||
|
|
|
@ -91,22 +91,6 @@ default: &defaults
|
||||||
encoding: utf8
|
encoding: utf8
|
||||||
socket: /opt/lampp/var/mysql/mysql.sock
|
socket: /opt/lampp/var/mysql/mysql.sock
|
||||||
|
|
||||||
# auto-units-conversion
|
|
||||||
# this is used for automatic article-synchronization to handle different units
|
|
||||||
# e.g. when foodcoop-unit should be 500g and supplier-unit is 1kg
|
|
||||||
units:
|
|
||||||
KG: 1
|
|
||||||
1kg: 1
|
|
||||||
500g: 0.5
|
|
||||||
400g: 0.4
|
|
||||||
300g: 0.3
|
|
||||||
250g: 0.25
|
|
||||||
200g: 0.2
|
|
||||||
150g: 0.15
|
|
||||||
125g: 0.125
|
|
||||||
100g: 0.1
|
|
||||||
50g: 0.05
|
|
||||||
|
|
||||||
development:
|
development:
|
||||||
<<: *defaults
|
<<: *defaults
|
||||||
|
|
||||||
|
|
37
config/initializers/ruby_units.rb
Normal file
37
config/initializers/ruby_units.rb
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
# add some more units
|
||||||
|
|
||||||
|
if defined? RubyUnits
|
||||||
|
RubyUnits::Unit.redefine!('liter') do |unit|
|
||||||
|
unit.aliases += %w{ltr}
|
||||||
|
end
|
||||||
|
|
||||||
|
RubyUnits::Unit.redefine!('kilogram') do |unit|
|
||||||
|
unit.aliases += %w{KG}
|
||||||
|
end
|
||||||
|
|
||||||
|
RubyUnits::Unit.redefine!('gram') do |unit|
|
||||||
|
unit.aliases += %w{gr}
|
||||||
|
end
|
||||||
|
|
||||||
|
RubyUnits::Unit.define('piece') do |unit|
|
||||||
|
unit.definition = RubyUnits::Unit.new('1 each')
|
||||||
|
unit.aliases = %w{pc pcs piece pieces} # locale: en
|
||||||
|
unit.aliases += %w{st stuk stuks} # locale: nl
|
||||||
|
unit.kind = :counting
|
||||||
|
end
|
||||||
|
|
||||||
|
# we use pc for piece, not parsec
|
||||||
|
RubyUnits::Unit.redefine!('parsec') do |unit|
|
||||||
|
unit.aliases = unit.aliases.reject {|u| u=='pc'}
|
||||||
|
unit.display_name = 'parsec'
|
||||||
|
end
|
||||||
|
|
||||||
|
# workaround for ruby-units' require mathn warning: "zero and implicit precision is deprecated."
|
||||||
|
# default precision of 8 which same as all database definitions in db/migrate/20131213002332_*.rb
|
||||||
|
class Rational
|
||||||
|
alias orig_to_d to_d
|
||||||
|
def to_d(precision=8)
|
||||||
|
orig_to_d(precision)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in a new issue