redmine_crm 0.0.7 → 0.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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