redmine_crm 0.0.23 → 0.0.53

Sign up to get free protection for your applications and to get access to all the features.
Files changed (103) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +4 -1
  3. data/README.md +166 -33
  4. data/Rakefile +3 -12
  5. data/app/controllers/redmine_crm_controller.rb +26 -0
  6. data/app/views/redmine_crm/_money.html.erb +44 -0
  7. data/app/views/redmine_crm/settings.html.erb +10 -0
  8. data/bitbucket-pipelines.yml +54 -0
  9. data/config/currency_iso.json +12 -0
  10. data/config/locales/en.yml +13 -0
  11. data/config/locales/ru.yml +13 -0
  12. data/config/routes.rb +5 -0
  13. data/doc/CHANGELOG +123 -2
  14. data/lib/redmine_crm/acts_as_draftable/draft.rb +40 -0
  15. data/lib/redmine_crm/acts_as_draftable/rcrm_acts_as_draftable.rb +172 -0
  16. data/lib/redmine_crm/acts_as_list/list.rb +282 -0
  17. data/lib/redmine_crm/{rcrm_acts_as_taggable.rb → acts_as_taggable/rcrm_acts_as_taggable.rb} +112 -93
  18. data/lib/redmine_crm/acts_as_taggable/tag.rb +81 -0
  19. data/lib/redmine_crm/acts_as_taggable/tag_list.rb +111 -0
  20. data/lib/redmine_crm/acts_as_taggable/tagging.rb +16 -0
  21. data/lib/redmine_crm/acts_as_viewed/rcrm_acts_as_viewed.rb +274 -0
  22. data/lib/redmine_crm/{rcrm_acts_as_votable.rb → acts_as_votable/rcrm_acts_as_votable.rb} +15 -14
  23. data/lib/redmine_crm/acts_as_votable/rcrm_acts_as_voter.rb +20 -0
  24. data/lib/redmine_crm/{votable.rb → acts_as_votable/votable.rb} +54 -65
  25. data/lib/redmine_crm/{vote.rb → acts_as_votable/vote.rb} +6 -8
  26. data/lib/redmine_crm/{voter.rb → acts_as_votable/voter.rb} +29 -34
  27. data/lib/redmine_crm/assets_manager.rb +43 -0
  28. data/lib/redmine_crm/colors_helper.rb +192 -0
  29. data/lib/redmine_crm/compatibility/application_controller_patch.rb +33 -0
  30. data/lib/redmine_crm/currency/formatting.rb +5 -8
  31. data/lib/redmine_crm/currency/heuristics.rb +1 -1
  32. data/lib/redmine_crm/currency/loader.rb +5 -6
  33. data/lib/redmine_crm/currency.rb +28 -17
  34. data/lib/redmine_crm/engine.rb +4 -0
  35. data/lib/redmine_crm/helpers/external_assets_helper.rb +19 -0
  36. data/lib/redmine_crm/helpers/form_tag_helper.rb +76 -0
  37. data/lib/redmine_crm/helpers/tags_helper.rb +1 -3
  38. data/lib/redmine_crm/helpers/vote_helper.rb +29 -32
  39. data/lib/redmine_crm/hooks/views_layouts_hook.rb +11 -0
  40. data/lib/redmine_crm/liquid/drops/issues_drop.rb +191 -0
  41. data/lib/redmine_crm/liquid/drops/news_drop.rb +54 -0
  42. data/lib/redmine_crm/liquid/drops/projects_drop.rb +86 -0
  43. data/lib/redmine_crm/liquid/drops/time_entries_drop.rb +65 -0
  44. data/lib/redmine_crm/liquid/drops/users_drop.rb +68 -0
  45. data/lib/redmine_crm/liquid/filters/arrays.rb +187 -0
  46. data/lib/redmine_crm/liquid/filters/base.rb +217 -0
  47. data/lib/redmine_crm/liquid/filters/colors.rb +31 -0
  48. data/lib/redmine_crm/money_helper.rb +17 -18
  49. data/lib/redmine_crm/settings/money.rb +46 -0
  50. data/lib/redmine_crm/settings.rb +53 -0
  51. data/lib/redmine_crm/version.rb +1 -1
  52. data/lib/redmine_crm.rb +60 -21
  53. data/redmine_crm.gemspec +12 -6
  54. data/test/acts_as_draftable/draft_test.rb +29 -0
  55. data/test/acts_as_draftable/rcrm_acts_as_draftable_test.rb +178 -0
  56. data/test/{acts_as_taggable_test.rb → acts_as_taggable/rcrm_acts_as_taggable_test.rb} +117 -156
  57. data/test/acts_as_taggable/tag_list_test.rb +34 -0
  58. data/test/acts_as_taggable/tag_test.rb +72 -0
  59. data/test/acts_as_taggable/tagging_test.rb +15 -0
  60. data/test/{viewed_test.rb → acts_as_viewed/rcrm_acts_as_viewed_test.rb} +17 -15
  61. data/test/acts_as_votable/rcrm_acts_as_votable_test.rb +19 -0
  62. data/test/acts_as_votable/rcrm_acts_as_voter_test.rb +14 -0
  63. data/test/{votable_model_test.rb → acts_as_votable/votable_test.rb} +34 -5
  64. data/test/{voter_model_test.rb → acts_as_votable/voter_test.rb} +8 -8
  65. data/test/currency_test.rb +10 -10
  66. data/test/database.yml +14 -14
  67. data/test/fixtures/issues.yml +13 -1
  68. data/test/fixtures/news.yml +8 -0
  69. data/test/fixtures/projects.yml +10 -0
  70. data/test/fixtures/users.yml +6 -2
  71. data/test/liquid/drops/issues_drop_test.rb +34 -0
  72. data/test/liquid/drops/news_drop_test.rb +38 -0
  73. data/test/liquid/drops/projects_drop_test.rb +44 -0
  74. data/test/liquid/drops/uses_drop_test.rb +36 -0
  75. data/test/liquid/filters/arrays_filter_test.rb +31 -0
  76. data/test/liquid/filters/base_filter_test.rb +63 -0
  77. data/test/liquid/filters/colors_filter_test.rb +33 -0
  78. data/test/liquid/liquid_helper.rb +34 -0
  79. data/test/models/issue.rb +14 -0
  80. data/test/models/news.rb +3 -0
  81. data/test/models/project.rb +8 -0
  82. data/test/{fixtures → models}/user.rb +5 -1
  83. data/test/{fixtures → models}/vote_classes.rb +0 -21
  84. data/test/money_helper_test.rb +5 -5
  85. data/test/schema.rb +33 -10
  86. data/test/test_helper.rb +20 -72
  87. data/vendor/assets/images/money.png +0 -0
  88. data/vendor/assets/images/vcard.png +0 -0
  89. data/vendor/assets/javascripts/Chart.bundle.min.js +16 -0
  90. data/vendor/assets/javascripts/select2.js +2 -0
  91. data/vendor/assets/javascripts/select2_helpers.js +192 -0
  92. data/vendor/assets/stylesheets/money.css +3 -0
  93. data/vendor/assets/stylesheets/select2.css +424 -0
  94. metadata +190 -40
  95. data/lib/redmine_crm/rcrm_acts_as_viewed.rb +0 -287
  96. data/lib/redmine_crm/rcrm_acts_as_voter.rb +0 -27
  97. data/lib/redmine_crm/tag.rb +0 -81
  98. data/lib/redmine_crm/tag_list.rb +0 -112
  99. data/lib/redmine_crm/tagging.rb +0 -20
  100. data/test/fixtures/issue.rb +0 -14
  101. data/test/tag_test.rb +0 -64
  102. data/test/tagging_test.rb +0 -14
  103. data/test/votable_test.rb +0 -17
@@ -1,9 +1,7 @@
1
1
  module RedmineCrm
2
2
  module ActsAsVotable
3
3
  module Voter
4
-
5
4
  def self.included(base)
6
-
7
5
  # allow user to define these
8
6
  aliases = {
9
7
  :vote_up_for => [:likes, :upvotes, :up_votes],
@@ -18,7 +16,6 @@ module RedmineCrm
18
16
  }
19
17
 
20
18
  base.class_eval do
21
-
22
19
  has_many :votes, :class_name => 'RedmineCrm::ActsAsVotable::Vote', :as => :voter, :dependent => :destroy do
23
20
  def votables
24
21
  includes(:votable).map(&:votable)
@@ -30,107 +27,105 @@ module RedmineCrm
30
27
  alias_method(new_method, method)
31
28
  end
32
29
  end
33
-
34
30
  end
35
-
36
31
  end
37
32
 
38
33
  # voting
39
- def vote args
40
- args[:votable].vote_by args.merge({:voter => self})
34
+ def vote(args)
35
+ args[:votable].vote_by args.merge(:voter => self)
41
36
  end
42
37
 
43
- def vote_up_for model=nil, args={}
38
+ def vote_up_for(model = nil, args = {})
44
39
  vote :votable => model, :vote_scope => args[:vote_scope], :vote => true
45
40
  end
46
41
 
47
- def vote_down_for model=nil, args={}
42
+ def vote_down_for(model = nil, args = {})
48
43
  vote :votable => model, :vote_scope => args[:vote_scope], :vote => false
49
44
  end
50
45
 
51
- def unvote_for model, args={}
46
+ def unvote_for(model, args = {})
52
47
  model.unvote :voter => self, :vote_scope => args[:vote_scope]
53
48
  end
54
49
 
55
50
  # results
56
- def voted_on? votable, args={}
51
+ def voted_on?(votable, args = {})
57
52
  votes = find_votes(:votable_id => votable.id, :votable_type => votable.class.base_class.name,
58
53
  :vote_scope => args[:vote_scope])
59
- votes.size > 0
54
+ !votes.empty?
60
55
  end
61
56
 
62
- def voted_up_on? votable, args={}
57
+ def voted_up_on?(votable, args = {})
63
58
  votes = find_votes(:votable_id => votable.id, :votable_type => votable.class.base_class.name,
64
59
  :vote_scope => args[:vote_scope], :vote_flag => true)
65
- votes.size > 0
60
+ !votes.empty?
66
61
  end
67
62
 
68
- def voted_down_on? votable, args={}
63
+ def voted_down_on?(votable, args = {})
69
64
  votes = find_votes(:votable_id => votable.id, :votable_type => votable.class.base_class.name,
70
65
  :vote_scope => args[:vote_scope], :vote_flag => false)
71
- votes.size > 0
66
+ !votes.empty?
72
67
  end
73
68
 
74
- def voted_as_when_voting_on votable, args={}
69
+ def voted_as_when_voting_on(votable, args = {})
75
70
  vote = find_votes(:votable_id => votable.id, :votable_type => votable.class.base_class.name,
76
- :vote_scope => args[:vote_scope]).select(:vote_flag).last
71
+ :vote_scope => args[:vote_scope]).select(:vote_flag).last
77
72
  return nil unless vote
78
- return vote.vote_flag
73
+ vote.vote_flag
79
74
  end
80
75
 
81
- def find_votes extra_conditions = {}
76
+ def find_votes(extra_conditions = {})
82
77
  votes.where(extra_conditions)
83
78
  end
84
79
 
85
- def find_up_votes args={}
80
+ def find_up_votes(args = {})
86
81
  find_votes :vote_flag => true, :vote_scope => args[:vote_scope]
87
82
  end
88
83
 
89
- def find_down_votes args={}
84
+ def find_down_votes(args = {})
90
85
  find_votes :vote_flag => false, :vote_scope => args[:vote_scope]
91
86
  end
92
87
 
93
- def find_votes_for_class klass, extra_conditions = {}
94
- find_votes extra_conditions.merge({:votable_type => klass.name})
88
+ def find_votes_for_class(klass, extra_conditions = {})
89
+ find_votes extra_conditions.merge(:votable_type => klass.name)
95
90
  end
96
91
 
97
- def find_up_votes_for_class klass, args={}
92
+ def find_up_votes_for_class(klass, args = {})
98
93
  find_votes_for_class klass, :vote_flag => true, :vote_scope => args[:vote_scope]
99
94
  end
100
95
 
101
- def find_down_votes_for_class klass, args={}
96
+ def find_down_votes_for_class(klass, args = {})
102
97
  find_votes_for_class klass, :vote_flag => false, :vote_scope => args[:vote_scope]
103
98
  end
104
99
 
105
100
  # Including polymporphic relations for eager loading
106
101
  def include_objects
107
- ActsAsVotable::Vote.includes(:votable)
102
+ RedmineCrm::ActsAsVotable::Vote.includes(:votable)
108
103
  end
109
104
 
110
- def find_voted_items extra_conditions = {}
105
+ def find_voted_items(extra_conditions = {})
111
106
  options = extra_conditions.merge :voter_id => id, :voter_type => self.class.base_class.name
112
107
  include_objects.where(options).collect(&:votable)
113
108
  end
114
109
 
115
- def find_up_voted_items extra_conditions = {}
110
+ def find_up_voted_items(extra_conditions = {})
116
111
  find_voted_items extra_conditions.merge(:vote_flag => true)
117
112
  end
118
113
 
119
- def find_down_voted_items extra_conditions = {}
114
+ def find_down_voted_items(extra_conditions = {})
120
115
  find_voted_items extra_conditions.merge(:vote_flag => false)
121
116
  end
122
117
 
123
- def get_voted klass, extra_conditions = {}
118
+ def get_voted(klass, extra_conditions = {})
124
119
  klass.joins(:votes_for).merge find_votes(extra_conditions)
125
120
  end
126
121
 
127
- def get_up_voted klass
122
+ def get_up_voted(klass)
128
123
  klass.joins(:votes_for).merge find_up_votes
129
124
  end
130
125
 
131
- def get_down_voted klass
126
+ def get_down_voted(klass)
132
127
  klass.joins(:votes_for).merge find_down_votes
133
128
  end
134
129
  end
135
130
  end
136
- end
131
+ end
@@ -0,0 +1,43 @@
1
+ module RedmineCrm
2
+ class AssetsManager
3
+ def self.install_assets
4
+ return unless Gem.loaded_specs[GEM_NAME]
5
+ source = File.join(Gem.loaded_specs[GEM_NAME].full_gem_path, 'vendor', 'assets')
6
+ destination = File.join(Dir.pwd, 'public', 'plugin_assets', GEM_NAME)
7
+ return unless File.directory?(source)
8
+
9
+ source_files = Dir[source + '/**/*']
10
+ source_dirs = source_files.select { |d| File.directory?(d) }
11
+ source_files -= source_dirs
12
+
13
+ unless source_files.empty?
14
+ base_target_dir = File.join(destination, File.dirname(source_files.first).gsub(source, ''))
15
+ begin
16
+ FileUtils.mkdir_p(base_target_dir)
17
+ rescue Exception => e
18
+ raise "Could not create directory #{base_target_dir}: " + e.message
19
+ end
20
+ end
21
+
22
+ source_dirs.each do |dir|
23
+ target_dir = File.join(destination, dir.gsub(source, ''))
24
+ begin
25
+ FileUtils.mkdir_p(target_dir)
26
+ rescue Exception => e
27
+ raise "Could not create directory #{target_dir}: " + e.message
28
+ end
29
+ end
30
+
31
+ source_files.each do |file|
32
+ begin
33
+ target = File.join(destination, file.gsub(source, ''))
34
+ unless File.exist?(target) && FileUtils.identical?(file, target)
35
+ FileUtils.cp(file, target)
36
+ end
37
+ rescue Exception => e
38
+ raise "Could not copy #{file} to #{target}: " + e.message
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,192 @@
1
+ module RedmineCrm
2
+ class ColorsHelper
3
+ NAMED_COLORS = {
4
+ 'aliceblue' => 'f0f8ff',
5
+ 'antiquewhite' => 'faebd7',
6
+ 'aqua' => '00ffff',
7
+ 'aquamarine' => '7fffd4',
8
+ 'azure' => 'f0ffff',
9
+ 'beige' => 'f5f5dc',
10
+ 'bisque' => 'ffe4c4',
11
+ 'black' => '000',
12
+ 'blanchedalmond' => 'ffebcd',
13
+ 'blue' => '0000ff',
14
+ 'blueviolet' => '8a2be2',
15
+ 'brown' => 'a52a2a',
16
+ 'burlywood' => 'deb887',
17
+ 'burntsienna' => 'ea7e5d',
18
+ 'cadetblue' => '5f9ea0',
19
+ 'chartreuse' => '7fff00',
20
+ 'chocolate' => 'd2691e',
21
+ 'coral' => 'ff7f50',
22
+ 'cornflowerblue' => '6495ed',
23
+ 'cornsilk' => 'fff8dc',
24
+ 'crimson' => 'dc143c',
25
+ 'cyan' => '00ffff',
26
+ 'darkblue' => '00008b',
27
+ 'darkcyan' => '008b8b',
28
+ 'darkgoldenrod' => 'b8860b',
29
+ 'darkgray' => 'a9a9a9',
30
+ 'darkgreen' => '006400',
31
+ 'darkgrey' => 'a9a9a9',
32
+ 'darkkhaki' => 'bdb76b',
33
+ 'darkmagenta' => '8b008b',
34
+ 'darkolivegreen' => '556b2f',
35
+ 'darkorange' => 'ff8c00',
36
+ 'darkorchid' => '9932cc',
37
+ 'darkred' => '8b0000',
38
+ 'darksalmon' => 'e9967a',
39
+ 'darkseagreen' => '8fbc8f',
40
+ 'darkslateblue' => '483d8b',
41
+ 'darkslategray' => '2f4f4f',
42
+ 'darkslategrey' => '2f4f4f',
43
+ 'darkturquoise' => '00ced1',
44
+ 'darkviolet' => '9400d3',
45
+ 'deeppink' => 'ff1493',
46
+ 'deepskyblue' => '00bfff',
47
+ 'dimgray' => '696969',
48
+ 'dimgrey' => '696969',
49
+ 'dodgerblue' => '1e90ff',
50
+ 'firebrick' => 'b22222',
51
+ 'floralwhite' => 'fffaf0',
52
+ 'forestgreen' => '228b22',
53
+ 'fuchsia' => 'ff00ff',
54
+ 'gainsboro' => 'dcdcdc',
55
+ 'ghostwhite' => 'f8f8ff',
56
+ 'gold' => 'ffd700',
57
+ 'goldenrod' => 'daa520',
58
+ 'gray' => '808080',
59
+ 'green' => '008000',
60
+ 'greenyellow' => 'adff2f',
61
+ 'grey' => '808080',
62
+ 'honeydew' => 'f0fff0',
63
+ 'hotpink' => 'ff69b4',
64
+ 'indianred' => 'cd5c5c',
65
+ 'indigo' => '4b0082',
66
+ 'ivory' => 'fffff0',
67
+ 'khaki' => 'f0e68c',
68
+ 'lavender' => 'e6e6fa',
69
+ 'lavenderblush' => 'fff0f5',
70
+ 'lawngreen' => '7cfc00',
71
+ 'lemonchiffon' => 'fffacd',
72
+ 'lightblue' => 'add8e6',
73
+ 'lightcoral' => 'f08080',
74
+ 'lightcyan' => 'e0ffff',
75
+ 'lightgoldenrodyellow' => 'fafad2',
76
+ 'lightgray' => 'd3d3d3',
77
+ 'lightgreen' => '90ee90',
78
+ 'lightgrey' => 'd3d3d3',
79
+ 'lightpink' => 'ffb6c1',
80
+ 'lightsalmon' => 'ffa07a',
81
+ 'lightseagreen' => '20b2aa',
82
+ 'lightskyblue' => '87cefa',
83
+ 'lightslategray' => '789',
84
+ 'lightslategrey' => '789',
85
+ 'lightsteelblue' => 'b0c4de',
86
+ 'lightyellow' => 'ffffe0',
87
+ 'lime' => '00ff00',
88
+ 'limegreen' => '32cd32',
89
+ 'linen' => 'faf0e6',
90
+ 'magenta' => 'ff00ff',
91
+ 'maroon' => '800000',
92
+ 'mediumaquamarine' => '66cdaa',
93
+ 'mediumblue' => '0000cd',
94
+ 'mediumorchid' => 'ba55d3',
95
+ 'mediumpurple' => '9370db',
96
+ 'mediumseagreen' => '3cb371',
97
+ 'mediumslateblue' => '7b68ee',
98
+ 'mediumspringgreen' => '00fa9a',
99
+ 'mediumturquoise' => '48d1cc',
100
+ 'mediumvioletred' => 'c71585',
101
+ 'midnightblue' => '191970',
102
+ 'mintcream' => 'f5fffa',
103
+ 'mistyrose' => 'ffe4e1',
104
+ 'moccasin' => 'ffe4b5',
105
+ 'navajowhite' => 'ffdead',
106
+ 'navy' => '000080',
107
+ 'oldlace' => 'fdf5e6',
108
+ 'olive' => '808000',
109
+ 'olivedrab' => '6b8e23',
110
+ 'orange' => 'ffa500',
111
+ 'orangered' => 'ff4500',
112
+ 'orchid' => 'da70d6',
113
+ 'palegoldenrod' => 'eee8aa',
114
+ 'palegreen' => '98fb98',
115
+ 'paleturquoise' => 'afeeee',
116
+ 'palevioletred' => 'db7093',
117
+ 'papayawhip' => 'ffefd5',
118
+ 'peachpuff' => 'ffdab9',
119
+ 'peru' => 'cd853f',
120
+ 'pink' => 'ffc0cb',
121
+ 'plum' => 'dda0dd',
122
+ 'powderblue' => 'b0e0e6',
123
+ 'purple' => '800080',
124
+ 'rebeccapurple' => '663399',
125
+ 'red' => 'ff0000',
126
+ 'rosybrown' => 'bc8f8f',
127
+ 'royalblue' => '4169e1',
128
+ 'saddlebrown' => '8b4513',
129
+ 'salmon' => 'fa8072',
130
+ 'sandybrown' => 'f4a460',
131
+ 'seagreen' => '2e8b57',
132
+ 'seashell' => 'fff5ee',
133
+ 'sienna' => 'a0522d',
134
+ 'silver' => 'c0c0c0',
135
+ 'skyblue' => '87ceeb',
136
+ 'slateblue' => '6a5acd',
137
+ 'slategray' => '708090',
138
+ 'slategrey' => '708090',
139
+ 'snow' => 'fffafa',
140
+ 'springgreen' => '00ff7f',
141
+ 'steelblue' => '4682b4',
142
+ 'tan' => 'd2b48c',
143
+ 'teal' => '008080',
144
+ 'thistle' => 'd8bfd8',
145
+ 'tomato' => 'ff6347',
146
+ 'turquoise' => '40e0d0',
147
+ 'violet' => 'ee82ee',
148
+ 'wheat' => 'f5deb3',
149
+ 'white' => 'fff',
150
+ 'whitesmoke' => 'f5f5f5',
151
+ 'yellow' => 'ffff00',
152
+ 'yellowgreen' => '9acd32'
153
+ }
154
+
155
+ class << self
156
+ # Amount should be a decimal between 0 and 1. Lower means darker
157
+
158
+ def darken_color(input_color, amount=0.4)
159
+ hex_color = hex_color(input_color).gsub('#','')
160
+ rgb = hex_color.scan(/../).map {|color| color.hex}
161
+ rgb[0] = (rgb[0].to_i * amount).round
162
+ rgb[1] = (rgb[1].to_i * amount).round
163
+ rgb[2] = (rgb[2].to_i * amount).round
164
+ "#%02x%02x%02x" % rgb
165
+ end
166
+
167
+ # Amount should be a decimal between 0 and 1. Higher lightgreen lighter
168
+ def lighten_color(input_color, amount=0.6)
169
+ hex_color = hex_color(input_color).gsub('#','')
170
+ rgb = hex_color.scan(/../).map {|color| color.hex}
171
+ rgb[0] = [(rgb[0].to_i + 255 * amount).round, 255].min
172
+ rgb[1] = [(rgb[1].to_i + 255 * amount).round, 255].min
173
+ rgb[2] = [(rgb[2].to_i + 255 * amount).round, 255].min
174
+ "#%02x%02x%02x" % rgb
175
+ end
176
+
177
+ def contrasting_text_color(input_color)
178
+ color = hex_color(input_color).gsub('#','')
179
+ convert_to_brightness_value(color) > 382.5 ? darken_color(color) : lighten_color(color)
180
+ end
181
+
182
+ def hex_color(input_color)
183
+ "##{NAMED_COLORS[input_color] || input_color}"
184
+ end
185
+
186
+ def convert_to_brightness_value(input_color)
187
+ (hex_color(input_color).scan(/../).map {|color| color.hex}).sum
188
+ end
189
+
190
+ end
191
+ end
192
+ end
@@ -0,0 +1,33 @@
1
+ module RedmineCrm
2
+ module Patches
3
+ module ApplicationControllerPatch
4
+ def self.included(base) # :nodoc:
5
+ base.extend(ClassMethods)
6
+ base.class_eval do
7
+ unloadable # Send unloadable so it will not be unloaded in development
8
+ end
9
+ end
10
+
11
+ module ClassMethods
12
+ def before_action(*filters, &block)
13
+ before_filter(*filters, &block)
14
+ end
15
+
16
+ def after_action(*filters, &block)
17
+ after_filter(*filters, &block)
18
+ end
19
+
20
+ def skip_before_action(*filters, &block)
21
+ skip_before_filter(*filters, &block)
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+
28
+ unless ActionController::Base.methods.include?(:before_action)
29
+ ActionController::Base.send(
30
+ :include,
31
+ RedmineCrm::Patches::ApplicationControllerPatch
32
+ )
33
+ end
@@ -4,8 +4,8 @@ module RedmineCrm
4
4
  module Formatting
5
5
  def self.included(base)
6
6
  [
7
- [:thousands_separator, :delimiter, ","],
8
- [:decimal_mark, :separator, "."]
7
+ [:thousands_separator, :delimiter, RedmineCrm::Settings::Money.thousands_delimiter],
8
+ [:decimal_mark, :separator, RedmineCrm::Settings::Money.decimal_separator]
9
9
  ].each do |method, name, character|
10
10
  define_i18n_method(method, name, character)
11
11
  end
@@ -26,7 +26,6 @@ module RedmineCrm
26
26
  alias_method name, method
27
27
  end
28
28
 
29
-
30
29
  def format(value, currency, *rules)
31
30
  # support for old format parameters
32
31
  rules = normalize_formatting_rules(rules)
@@ -116,9 +115,9 @@ module RedmineCrm
116
115
 
117
116
  def default_formatting_rules
118
117
  {
119
- :decimal_mark =>".",
120
- :thousands_separator => ",",
121
- :subunit_to_unit => 100
118
+ decimal_mark: RedmineCrm::Settings::Money.decimal_separator || '.',
119
+ thousands_separator: RedmineCrm::Settings::Money.thousands_delimiter || ',',
120
+ subunit_to_unit: 100
122
121
  }
123
122
  end
124
123
 
@@ -220,8 +219,6 @@ module RedmineCrm
220
219
  "\\1#{rules[:decimal_mark]}\\3")
221
220
  end
222
221
  end
223
-
224
222
  end
225
-
226
223
  end
227
224
  end
@@ -148,4 +148,4 @@ module RedmineCrm
148
148
  end
149
149
  end
150
150
  end
151
- end
151
+ end
@@ -3,13 +3,12 @@ module RedmineCrm
3
3
  module Loader
4
4
  DATA_PATH = File.expand_path("../../../../config", __FILE__)
5
5
 
6
- # Loads and returns the currencies stored in JSON files in the config directory.
6
+ # Loads and returns the currencies stored in JSON files
7
+ # in the config directory.
7
8
  #
8
9
  # @return [Hash]
9
10
  def load_currencies
10
- currencies = parse_currency_file("currency_iso.json")
11
- # currencies.merge! parse_currency_file("currency_non_iso.json")
12
- # currencies.merge! parse_currency_file("currency_backwards_compatible.json")
11
+ parse_currency_file('currency_iso.json')
13
12
  end
14
13
 
15
14
  private
@@ -17,8 +16,8 @@ module RedmineCrm
17
16
  def parse_currency_file(filename)
18
17
  json = File.read("#{DATA_PATH}/#{filename}")
19
18
  json.force_encoding(::Encoding::UTF_8) if defined?(::Encoding)
20
- JSON.parse(json, :symbolize_names => true)
19
+ JSON.parse(json, symbolize_names: true)
21
20
  end
22
21
  end
23
22
  end
24
- end
23
+ end
@@ -33,6 +33,17 @@ module RedmineCrm
33
33
 
34
34
  class << self
35
35
 
36
+ def add_admin_money_menu
37
+ return if Redmine::MenuManager.map(:admin_menu).exists?(:redmine_crm_money)
38
+
39
+ require 'redmine_crm/hooks/views_layouts_hook'
40
+ Redmine::MenuManager.map(:admin_menu).push(:redmine_crm_money,
41
+ { controller: 'redmine_crm', action: 'settings', id: 'money' },
42
+ caption: :label_redmine_crm_money,
43
+ html: { class: 'icon icon-redminecrm-money' })
44
+
45
+ end
46
+
36
47
  # Lookup a currency with given +id+ an returns a +Currency+ instance on
37
48
  # success, +nil+ otherwise.
38
49
  #
@@ -190,40 +201,40 @@ module RedmineCrm
190
201
  end
191
202
  end
192
203
 
193
- # @!attribute [r] id
204
+ # @!attribute [r] id
194
205
  # @return [Symbol] The symbol used to identify the currency, usually THE
195
206
  # lowercase +iso_code+ attribute.
196
- # @!attribute [r] priority
207
+ # @!attribute [r] priority
197
208
  # @return [Integer] A numerical value you can use to sort/group the
198
209
  # currency list.
199
- # @!attribute [r] iso_code
210
+ # @!attribute [r] iso_code
200
211
  # @return [String] The international 3-letter code as defined by the ISO
201
212
  # 4217 standard.
202
- # @!attribute [r] iso_numeric
213
+ # @!attribute [r] iso_numeric
203
214
  # @return [String] The international 3-numeric code as defined by the ISO
204
215
  # 4217 standard.
205
- # @!attribute [r] name
216
+ # @!attribute [r] name
206
217
  # @return [String] The currency name.
207
- # @!attribute [r] symbol
218
+ # @!attribute [r] symbol
208
219
  # @return [String] The currency symbol (UTF-8 encoded).
209
- # @!attribute [r] disambiguate_symbol
220
+ # @!attribute [r] disambiguate_symbol
210
221
  # @return [String] Alternative currency used if symbol is ambiguous
211
- # @!attribute [r] html_entity
222
+ # @!attribute [r] html_entity
212
223
  # @return [String] The html entity for the currency symbol
213
- # @!attribute [r] subunit
224
+ # @!attribute [r] subunit
214
225
  # @return [String] The name of the fractional monetary unit.
215
- # @!attribute [r] subunit_to_unit
226
+ # @!attribute [r] subunit_to_unit
216
227
  # @return [Integer] The proportion between the unit and the subunit
217
- # @!attribute [r] decimal_mark
228
+ # @!attribute [r] decimal_mark
218
229
  # @return [String] The decimal mark, or character used to separate the
219
230
  # whole unit from the subunit.
220
- # @!attribute [r] The
231
+ # @!attribute [r] The
221
232
  # @return [String] character used to separate thousands grouping of the
222
233
  # whole unit.
223
- # @!attribute [r] symbol_first
234
+ # @!attribute [r] symbol_first
224
235
  # @return [Boolean] Should the currency symbol precede the amount, or
225
236
  # should it come after?
226
- # @!attribute [r] smallest_denomination
237
+ # @!attribute [r] smallest_denomination
227
238
  # @return [Integer] Smallest amount of cash possible (in the subunit of
228
239
  # this currency)
229
240
 
@@ -301,7 +312,7 @@ module RedmineCrm
301
312
  end
302
313
  self.id.to_s.downcase == other_currency_id
303
314
  end
304
-
315
+
305
316
  private :compare_ids
306
317
 
307
318
  # Returns a Fixnum hash value based on the +id+ attribute in order to use
@@ -402,7 +413,7 @@ module RedmineCrm
402
413
  end
403
414
 
404
415
  private
405
-
416
+
406
417
  def cache
407
418
  self.class.decimal_places_cache
408
419
  end
@@ -436,4 +447,4 @@ module RedmineCrm
436
447
  @thousands_separator = data[:thousands_separator]
437
448
  end
438
449
  end
439
- end
450
+ end
@@ -0,0 +1,4 @@
1
+ module RedmineCrm
2
+ class Engine < Rails::Engine
3
+ end
4
+ end
@@ -0,0 +1,19 @@
1
+ module RedmineCrm
2
+ module ExternalAssetsHelper
3
+ include ActionView::Helpers::JavaScriptHelper
4
+
5
+ def select2_assets
6
+ return if @select2_tag_included
7
+ @select2_tag_included = true
8
+ javascript_include_tag('select2', plugin: GEM_NAME) +
9
+ stylesheet_link_tag('select2', plugin: GEM_NAME) +
10
+ javascript_include_tag('select2_helpers', plugin: GEM_NAME)
11
+ end
12
+
13
+ def chartjs_assets
14
+ return if @chartjs_tag_included
15
+ @chartjs_tag_included = true
16
+ javascript_include_tag('Chart.bundle.min', plugin: GEM_NAME)
17
+ end
18
+ end
19
+ end