redmine_crm 0.0.7 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3661b03ec0c3d09a9c41e80181930cd950f00cbe
4
- data.tar.gz: 953749b65190d3682c9aed7a8ecca66174c9c78e
3
+ metadata.gz: 6c8441e8bec7aa49ee5f7c391e66cc174da87266
4
+ data.tar.gz: dfddb0ee0c407a3e3d6bc1d6e4ff91bf3e6816df
5
5
  SHA512:
6
- metadata.gz: e2bfe39d6138293c2ac1456003cf885094b7961f6c30e87b4bf1276bcd7a565746a58bbd489c98454f0afc71aa8b8f21fe02573dd063bd7bb3d90d9bcefe0f36
7
- data.tar.gz: c85726be43588829945a3f84c300e9d0345bfc9c0d7149fc4c5080db507b587a796c77bfbe5a206366b469509929f0eb7a5e8de5401845c87800f95aee880ef3
6
+ metadata.gz: 56a5b5fc3381ee13dff3740e0c0f027b13db220e5571f1027b3829acf74eddeaa76102f9dca14cd3dbe8122c57862130c44af839c4b02115ec8d2f5f4741827a
7
+ data.tar.gz: 34b79fa7e7ca483f9e3ad606c92e421f8409617ffa7f623d6a5018b26ad4f2280c3577ec464ed48f2f1e75104633e7336d1d5ad6d533f68dc744080890aacdf0
data/lib/redmine_crm.rb CHANGED
@@ -6,3 +6,4 @@ require "redmine_crm/tagging"
6
6
  require "redmine_crm/rcrm_acts_as_taggable"
7
7
  require "redmine_crm/tags_helper"
8
8
  require "redmine_crm/currency"
9
+ require "redmine_crm/money_helper"
@@ -1,6 +1,8 @@
1
1
  require "json"
2
2
  require "redmine_crm/currency/loader"
3
3
  require "redmine_crm/currency/heuristics"
4
+ require "redmine_crm/currency/formatting"
5
+
4
6
  module RedmineCrm
5
7
  # Represents a specific currency unit.
6
8
  #
@@ -11,6 +13,9 @@ module RedmineCrm
11
13
  extend Enumerable
12
14
  extend RedmineCrm::Currency::Loader
13
15
  extend RedmineCrm::Currency::Heuristics
16
+ extend RedmineCrm::Currency::Formatting
17
+
18
+
14
19
 
15
20
  # Thrown when a Currency has been registered without all the attributes
16
21
  # which are required for the current action.
@@ -177,7 +182,6 @@ module RedmineCrm
177
182
  all.each { |c| yield(c) }
178
183
  end
179
184
 
180
-
181
185
  private
182
186
 
183
187
  def stringify_keys
@@ -296,6 +300,7 @@ module RedmineCrm
296
300
  end
297
301
  self.id.to_s.downcase == other_currency_id
298
302
  end
303
+
299
304
  private :compare_ids
300
305
 
301
306
  # Returns a Fixnum hash value based on the +id+ attribute in order to use
@@ -396,7 +401,7 @@ module RedmineCrm
396
401
  end
397
402
 
398
403
  private
399
-
404
+
400
405
  def cache
401
406
  self.class.decimal_places_cache
402
407
  end
@@ -0,0 +1,221 @@
1
+ # encoding: UTF-8
2
+ module RedmineCrm
3
+ class Currency
4
+ module Formatting
5
+ def self.included(base)
6
+ [
7
+ [:thousands_separator, :delimiter, ","],
8
+ [:decimal_mark, :separator, "."]
9
+ ].each do |method, name, character|
10
+ define_i18n_method(method, name, character)
11
+ end
12
+ end
13
+
14
+ def self.define_i18n_method(method, name, character)
15
+ define_method(method) do
16
+ if self.class.use_i18n
17
+ begin
18
+ I18n.t name, :scope => "number.currency.format", :raise => true
19
+ rescue I18n::MissingTranslationData
20
+ I18n.t name, :scope =>"number.format", :default => (currency.send(method) || character)
21
+ end
22
+ else
23
+ currency.send(method) || character
24
+ end
25
+ end
26
+ alias_method name, method
27
+ end
28
+
29
+
30
+ def format(value, currency, *rules)
31
+ # support for old format parameters
32
+ rules = normalize_formatting_rules(rules)
33
+ # byebug
34
+ rules = Currency.default_formatting_rules.merge(rules)
35
+ rules = self.localize_formatting_rules(rules, currency)
36
+ rules = self.translate_formatting_rules(rules, currency.code) if rules[:translate]
37
+
38
+ # if fractional == 0
39
+ if rules[:display_free].respond_to?(:to_str)
40
+ return rules[:display_free]
41
+ elsif rules[:display_free]
42
+ return "free"
43
+ end
44
+ # end
45
+
46
+ symbol_value = currency.symbol
47
+
48
+ formatted = value.abs.to_s
49
+
50
+ # if rules[:rounded_infinite_precision]
51
+ formatted.gsub!(/#{currency.decimal_mark}/, '.') unless '.' == currency.decimal_mark
52
+ formatted = ((BigDecimal(formatted) * currency.subunit_to_unit).round / BigDecimal(currency.subunit_to_unit.to_s)).to_s("F")
53
+ formatted.gsub!(/\..*/) do |decimal_part|
54
+ decimal_part << '0' while decimal_part.length < (currency.decimal_places + 1)
55
+ decimal_part
56
+ end
57
+ formatted.gsub!(/\./, currency.decimal_mark) unless '.' == currency.decimal_mark
58
+ # end
59
+
60
+ sign = value < 0 ? '-' : ''
61
+
62
+ if rules[:no_cents] || (rules[:no_cents_if_whole] && cents % currency.subunit_to_unit == 0)
63
+ formatted = "#{formatted.to_i}"
64
+ end
65
+
66
+ thousands_separator_value = currency.thousands_separator
67
+ # Determine thousands_separator
68
+ if rules.has_key?(:thousands_separator)
69
+ thousands_separator_value = rules[:thousands_separator] || ''
70
+ end
71
+
72
+ # Apply thousands_separator
73
+ formatted.gsub!(regexp_format(formatted, rules, currency.decimal_mark, symbol_value),
74
+ "\\1#{thousands_separator_value}")
75
+
76
+ symbol_position = symbol_position_from(rules, currency)
77
+
78
+ if rules[:sign_positive] == true && (value >= 0)
79
+ sign = '+'
80
+ end
81
+
82
+ if rules[:sign_before_symbol] == true
83
+ sign_before = sign
84
+ sign = ''
85
+ end
86
+
87
+ if symbol_value && !symbol_value.empty?
88
+ symbol_value = "<span class=\"currency_symbol\">#{symbol_value}</span>" if rules[:html_wrap_symbol]
89
+
90
+ formatted = if symbol_position == :before
91
+ symbol_space = rules[:symbol_before_without_space] === false ? " " : ""
92
+ "#{sign_before}#{symbol_value}#{symbol_space}#{sign}#{formatted}"
93
+ else
94
+ symbol_space = rules[:symbol_after_without_space] ? "" : " "
95
+ "#{sign_before}#{sign}#{formatted}#{symbol_space}#{symbol_value}"
96
+ end
97
+ else
98
+ formatted="#{sign_before}#{sign}#{formatted}"
99
+ end
100
+
101
+ apply_decimal_mark_from_rules(formatted, rules)
102
+
103
+ if rules[:with_currency]
104
+ formatted << " "
105
+ formatted << '<span class="currency">' if rules[:html]
106
+ formatted << currency.to_s
107
+ formatted << '</span>' if rules[:html]
108
+ end
109
+ formatted
110
+ end
111
+
112
+ def default_formatting_rules
113
+ # byebug
114
+ {}
115
+ end
116
+
117
+ def regexp_format(formatted, rules, decimal_mark, symbol_value)
118
+ regexp_decimal = Regexp.escape(decimal_mark)
119
+ if rules[:south_asian_number_formatting]
120
+ /(\d+?)(?=(\d\d)+(\d)(?:\.))/
121
+ else
122
+ # Symbols may contain decimal marks (E.g "դր.")
123
+ if formatted.sub(symbol_value.to_s, "") =~ /#{regexp_decimal}/
124
+ /(\d)(?=(?:\d{3})+(?:#{regexp_decimal}))/
125
+ else
126
+ /(\d)(?=(?:\d{3})+(?:[^\d]{1}|$))/
127
+ end
128
+ end
129
+ end
130
+
131
+ def translate_formatting_rules(rules, iso_code)
132
+ begin
133
+ rules[:symbol] = I18n.t iso_code, :scope => "number.currency.symbol", :raise => true
134
+ rescue I18n::MissingTranslationData
135
+ # Do nothing
136
+ end
137
+ rules
138
+ end
139
+
140
+ def localize_formatting_rules(rules, currency)
141
+ if currency.iso_code == "JPY" && I18n.locale == :ja
142
+ rules[:symbol] = "円" unless rules[:symbol] == false
143
+ rules[:symbol_position] = :after
144
+ rules[:symbol_after_without_space] = true
145
+ end
146
+ rules
147
+ end
148
+
149
+ def symbol_value_from(rules)
150
+ if rules.has_key?(:symbol)
151
+ if rules[:symbol] === true
152
+ symbol
153
+ elsif rules[:symbol]
154
+ rules[:symbol]
155
+ else
156
+ ""
157
+ end
158
+ elsif rules[:html]
159
+ currency.html_entity == '' ? currency.symbol : currency.html_entity
160
+ elsif rules[:disambiguate] and currency.disambiguate_symbol
161
+ currency.disambiguate_symbol
162
+ else
163
+ symbol
164
+ end
165
+ end
166
+
167
+ def symbol_position_from(rules, currency)
168
+ if rules.has_key?(:symbol_position)
169
+ if [:before, :after].include?(rules[:symbol_position])
170
+ return rules[:symbol_position]
171
+ else
172
+ raise ArgumentError, ":symbol_position must be ':before' or ':after'"
173
+ end
174
+ elsif currency.symbol_first?
175
+ :before
176
+ else
177
+ :after
178
+ end
179
+ end
180
+
181
+ private
182
+
183
+ # Cleans up formatting rules.
184
+ #
185
+ # @param [Hash] rules
186
+ #
187
+ # @return [Hash]
188
+ def normalize_formatting_rules(rules)
189
+ if rules.size == 0
190
+ rules = {}
191
+ elsif rules.size == 1
192
+ rules = rules.pop
193
+ rules = { rules => true } if rules.is_a?(Symbol)
194
+ end
195
+ if !rules.include?(:decimal_mark) && rules.include?(:separator)
196
+ rules[:decimal_mark] = rules[:separator]
197
+ end
198
+ if !rules.include?(:thousands_separator) && rules.include?(:delimiter)
199
+ rules[:thousands_separator] = rules[:delimiter]
200
+ end
201
+ rules
202
+ end
203
+
204
+ # Applies decimal mark from rules to formatted
205
+ #
206
+ # @param [String] formatted
207
+ # @param [Hash] rules
208
+ def apply_decimal_mark_from_rules(formatted, rules)
209
+ if rules.has_key?(:decimal_mark) && rules[:decimal_mark] &&
210
+ rules[:decimal_mark] != decimal_mark
211
+
212
+ regexp_decimal = Regexp.escape(decimal_mark)
213
+ formatted.sub!(/(.*)(#{regexp_decimal})(.*)\Z/,
214
+ "\\1#{rules[:decimal_mark]}\\3")
215
+ end
216
+ end
217
+
218
+ end
219
+
220
+ end
221
+ end
@@ -0,0 +1,71 @@
1
+ # byebug
2
+ # require 'action_controller'
3
+ require 'action_view'
4
+
5
+ module RedmineCrm
6
+ module MoneyHelper
7
+
8
+ def object_price(obj, price_field = :price)
9
+ price_to_currency(obj.try(price_field), obj.currency, :symbol => true).to_s if obj.respond_to?(:currency)
10
+ end
11
+
12
+ def prices_collection_by_currency(prices_collection, options={})
13
+ return [] if prices_collection.blank? || prices_collection == 0
14
+ prices = prices_collection
15
+ prices.reject!{|k, v| v.to_i == 0} if options[:hide_zeros]
16
+ prices.collect{|k, v| content_tag(:span, price_to_currency(v, k, :symbol => true), :style => "white-space: nowrap;")}.compact
17
+ end
18
+
19
+ def deal_currency_icon(currency)
20
+ case currency.to_s.upcase
21
+ when 'EUR'
22
+ "icon-money-euro"
23
+ when 'GBP'
24
+ "icon-money-pound"
25
+ when 'JPY'
26
+ "icon-money-yen"
27
+ else
28
+ "icon-money-dollar"
29
+ end
30
+ end
31
+
32
+ def collection_for_currencies_select(default_currency = ContactsSetting.default_currency)
33
+ major_currencies_collection(default_currency)
34
+ end
35
+
36
+ def major_currencies_collection(default_currency)
37
+ currencies = []
38
+ currencies << default_currency.to_s unless default_currency.blank?
39
+ currencies |= ContactsSetting.major_currencies
40
+ currencies.map do |c|
41
+ currency = RedmineCrm::Currency.find(c)
42
+ ["#{currency.iso_code} (#{currency.symbol})", currency.iso_code] if currency
43
+ end.compact.uniq
44
+ end
45
+
46
+ def all_currencies
47
+ Currency.table.inject([]) do |array, (id, attributes)|
48
+ array ||= []
49
+ array << ["#{attributes[:name]}" + (attributes[:symbol].blank? ? "" : " (#{attributes[:symbol]})"), attributes[:iso_code]]
50
+ array
51
+ end.sort{|x, y| x[0] <=> y[0]}
52
+ end
53
+
54
+ def price_to_currency(price, currency=RedmineCrm::Currency.find("USD"), options={})
55
+ return '' if price.blank?
56
+
57
+ if currency.is_a? String
58
+ currency = RedmineCrm::Currency.find(currency)
59
+ else
60
+ currency = RedmineCrm::Currency.find("USD")
61
+ end
62
+ RedmineCrm::Currency.format(price.to_f, currency)
63
+ end
64
+
65
+
66
+ end
67
+ end
68
+
69
+ unless ActionView::Base.included_modules.include?(RedmineCrm::MoneyHelper)
70
+ ActionView::Base.send(:include, RedmineCrm::MoneyHelper)
71
+ end
@@ -93,7 +93,7 @@ module RedmineCrm
93
93
 
94
94
  return [] if related_models.blank?
95
95
 
96
- related_ids = related_models.ids.join(",")
96
+ related_ids = related_models.map{|c| c.id }.join(",")
97
97
  Tag.select( #find(:all, options.merge({
98
98
  "#{Tag.table_name}.*, COUNT(#{Tag.table_name}.id) AS count").joins(
99
99
  "JOIN #{Tagging.table_name} ON #{Tagging.table_name}.taggable_type = '#{base_class.name}'
@@ -112,7 +112,7 @@ module RedmineCrm
112
112
  # :conditions - A piece of SQL conditions to add to the query
113
113
  def find_tagged_with(*args)
114
114
  options = find_options_for_find_tagged_with(*args)
115
- options.blank? ? [] : select(options[:select]).where(options[:conditions]).joins(options[:joins]).order(options[:order])
115
+ options.blank? ? [] : select(options[:select]).where(options[:conditions]).joins(options[:joins]).order(options[:order]).to_a
116
116
  # find(:all, options)
117
117
  end
118
118
  alias_method :tagged_with, :find_tagged_with
@@ -148,7 +148,7 @@ module RedmineCrm
148
148
  end
149
149
  end
150
150
 
151
- { :select => "DISTINCT #{table_name}.id ",
151
+ { :select => "DISTINCT #{table_name}.* ",
152
152
  :joins => joins.join(" "),
153
153
  :conditions => conditions.join(" AND ")
154
154
  }.reverse_merge!(options)
@@ -1,3 +1,3 @@
1
1
  module RedmineCrm
2
- VERSION = "0.0.7"
2
+ VERSION = "0.0.8"
3
3
  end
@@ -0,0 +1,10 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ class MoneyHelperTest < ActiveSupport::TestCase
4
+ include RedmineCrm::MoneyHelper
5
+
6
+ def test_price_to_currency
7
+ assert_equal '$3,265.65', price_to_currency(3265.65, "USD")
8
+ assert_equal "3.265,65 ₽", price_to_currency(3265.65, "RUB")
9
+ end
10
+ end
data/test/tag_test.rb CHANGED
@@ -11,7 +11,7 @@ module RedmineCrm
11
11
  t = Tag.create!(:name => "My tag")
12
12
  duplicate = t.dup
13
13
  assert !duplicate.save
14
- assert_match /taken/, duplicate.errors[:name].to_s
14
+ assert_match /not uniq/, duplicate.errors[:name].to_s
15
15
  end
16
16
 
17
17
  def test_taggings
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: redmine_crm
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7
4
+ version: 0.0.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - RedmineCRM
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-06-08 00:00:00.000000000 Z
11
+ date: 2015-06-10 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: plugins for Redmine
14
14
  email:
@@ -27,8 +27,10 @@ files:
27
27
  - lib/generators/redmine_crm_migration/templates/migration.rb
28
28
  - lib/redmine_crm.rb
29
29
  - lib/redmine_crm/currency.rb
30
+ - lib/redmine_crm/currency/formatting.rb
30
31
  - lib/redmine_crm/currency/heuristics.rb
31
32
  - lib/redmine_crm/currency/loader.rb
33
+ - lib/redmine_crm/money_helper.rb
32
34
  - lib/redmine_crm/rcrm_acts_as_taggable.rb
33
35
  - lib/redmine_crm/tag.rb
34
36
  - lib/redmine_crm/tag_list.rb
@@ -45,6 +47,7 @@ files:
45
47
  - test/fixtures/tags.yml
46
48
  - test/fixtures/user.rb
47
49
  - test/fixtures/users.yml
50
+ - test/money_helper_test.rb
48
51
  - test/schema.rb
49
52
  - test/tag_test.rb
50
53
  - test/tagging_test.rb
@@ -84,6 +87,7 @@ test_files:
84
87
  - test/fixtures/tags.yml
85
88
  - test/fixtures/user.rb
86
89
  - test/fixtures/users.yml
90
+ - test/money_helper_test.rb
87
91
  - test/schema.rb
88
92
  - test/tag_test.rb
89
93
  - test/tagging_test.rb