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.
- checksums.yaml +4 -4
- data/.gitignore +4 -1
- data/README.md +166 -33
- data/Rakefile +3 -12
- data/app/controllers/redmine_crm_controller.rb +26 -0
- data/app/views/redmine_crm/_money.html.erb +44 -0
- data/app/views/redmine_crm/settings.html.erb +10 -0
- data/bitbucket-pipelines.yml +54 -0
- data/config/currency_iso.json +12 -0
- data/config/locales/en.yml +13 -0
- data/config/locales/ru.yml +13 -0
- data/config/routes.rb +5 -0
- data/doc/CHANGELOG +123 -2
- data/lib/redmine_crm/acts_as_draftable/draft.rb +40 -0
- data/lib/redmine_crm/acts_as_draftable/rcrm_acts_as_draftable.rb +172 -0
- data/lib/redmine_crm/acts_as_list/list.rb +282 -0
- data/lib/redmine_crm/{rcrm_acts_as_taggable.rb → acts_as_taggable/rcrm_acts_as_taggable.rb} +112 -93
- data/lib/redmine_crm/acts_as_taggable/tag.rb +81 -0
- data/lib/redmine_crm/acts_as_taggable/tag_list.rb +111 -0
- data/lib/redmine_crm/acts_as_taggable/tagging.rb +16 -0
- data/lib/redmine_crm/acts_as_viewed/rcrm_acts_as_viewed.rb +274 -0
- data/lib/redmine_crm/{rcrm_acts_as_votable.rb → acts_as_votable/rcrm_acts_as_votable.rb} +15 -14
- data/lib/redmine_crm/acts_as_votable/rcrm_acts_as_voter.rb +20 -0
- data/lib/redmine_crm/{votable.rb → acts_as_votable/votable.rb} +54 -65
- data/lib/redmine_crm/{vote.rb → acts_as_votable/vote.rb} +6 -8
- data/lib/redmine_crm/{voter.rb → acts_as_votable/voter.rb} +29 -34
- data/lib/redmine_crm/assets_manager.rb +43 -0
- data/lib/redmine_crm/colors_helper.rb +192 -0
- data/lib/redmine_crm/compatibility/application_controller_patch.rb +33 -0
- data/lib/redmine_crm/currency/formatting.rb +5 -8
- data/lib/redmine_crm/currency/heuristics.rb +1 -1
- data/lib/redmine_crm/currency/loader.rb +5 -6
- data/lib/redmine_crm/currency.rb +28 -17
- data/lib/redmine_crm/engine.rb +4 -0
- data/lib/redmine_crm/helpers/external_assets_helper.rb +19 -0
- data/lib/redmine_crm/helpers/form_tag_helper.rb +76 -0
- data/lib/redmine_crm/helpers/tags_helper.rb +1 -3
- data/lib/redmine_crm/helpers/vote_helper.rb +29 -32
- data/lib/redmine_crm/hooks/views_layouts_hook.rb +11 -0
- data/lib/redmine_crm/liquid/drops/issues_drop.rb +191 -0
- data/lib/redmine_crm/liquid/drops/news_drop.rb +54 -0
- data/lib/redmine_crm/liquid/drops/projects_drop.rb +86 -0
- data/lib/redmine_crm/liquid/drops/time_entries_drop.rb +65 -0
- data/lib/redmine_crm/liquid/drops/users_drop.rb +68 -0
- data/lib/redmine_crm/liquid/filters/arrays.rb +187 -0
- data/lib/redmine_crm/liquid/filters/base.rb +217 -0
- data/lib/redmine_crm/liquid/filters/colors.rb +31 -0
- data/lib/redmine_crm/money_helper.rb +17 -18
- data/lib/redmine_crm/settings/money.rb +46 -0
- data/lib/redmine_crm/settings.rb +53 -0
- data/lib/redmine_crm/version.rb +1 -1
- data/lib/redmine_crm.rb +60 -21
- data/redmine_crm.gemspec +12 -6
- data/test/acts_as_draftable/draft_test.rb +29 -0
- data/test/acts_as_draftable/rcrm_acts_as_draftable_test.rb +178 -0
- data/test/{acts_as_taggable_test.rb → acts_as_taggable/rcrm_acts_as_taggable_test.rb} +117 -156
- data/test/acts_as_taggable/tag_list_test.rb +34 -0
- data/test/acts_as_taggable/tag_test.rb +72 -0
- data/test/acts_as_taggable/tagging_test.rb +15 -0
- data/test/{viewed_test.rb → acts_as_viewed/rcrm_acts_as_viewed_test.rb} +17 -15
- data/test/acts_as_votable/rcrm_acts_as_votable_test.rb +19 -0
- data/test/acts_as_votable/rcrm_acts_as_voter_test.rb +14 -0
- data/test/{votable_model_test.rb → acts_as_votable/votable_test.rb} +34 -5
- data/test/{voter_model_test.rb → acts_as_votable/voter_test.rb} +8 -8
- data/test/currency_test.rb +10 -10
- data/test/database.yml +14 -14
- data/test/fixtures/issues.yml +13 -1
- data/test/fixtures/news.yml +8 -0
- data/test/fixtures/projects.yml +10 -0
- data/test/fixtures/users.yml +6 -2
- data/test/liquid/drops/issues_drop_test.rb +34 -0
- data/test/liquid/drops/news_drop_test.rb +38 -0
- data/test/liquid/drops/projects_drop_test.rb +44 -0
- data/test/liquid/drops/uses_drop_test.rb +36 -0
- data/test/liquid/filters/arrays_filter_test.rb +31 -0
- data/test/liquid/filters/base_filter_test.rb +63 -0
- data/test/liquid/filters/colors_filter_test.rb +33 -0
- data/test/liquid/liquid_helper.rb +34 -0
- data/test/models/issue.rb +14 -0
- data/test/models/news.rb +3 -0
- data/test/models/project.rb +8 -0
- data/test/{fixtures → models}/user.rb +5 -1
- data/test/{fixtures → models}/vote_classes.rb +0 -21
- data/test/money_helper_test.rb +5 -5
- data/test/schema.rb +33 -10
- data/test/test_helper.rb +20 -72
- data/vendor/assets/images/money.png +0 -0
- data/vendor/assets/images/vcard.png +0 -0
- data/vendor/assets/javascripts/Chart.bundle.min.js +16 -0
- data/vendor/assets/javascripts/select2.js +2 -0
- data/vendor/assets/javascripts/select2_helpers.js +192 -0
- data/vendor/assets/stylesheets/money.css +3 -0
- data/vendor/assets/stylesheets/select2.css +424 -0
- metadata +190 -40
- data/lib/redmine_crm/rcrm_acts_as_viewed.rb +0 -287
- data/lib/redmine_crm/rcrm_acts_as_voter.rb +0 -27
- data/lib/redmine_crm/tag.rb +0 -81
- data/lib/redmine_crm/tag_list.rb +0 -112
- data/lib/redmine_crm/tagging.rb +0 -20
- data/test/fixtures/issue.rb +0 -14
- data/test/tag_test.rb +0 -64
- data/test/tagging_test.rb +0 -14
- 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
|
40
|
-
args[:votable].vote_by args.merge(
|
34
|
+
def vote(args)
|
35
|
+
args[:votable].vote_by args.merge(:voter => self)
|
41
36
|
end
|
42
37
|
|
43
|
-
def vote_up_for
|
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
|
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
|
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?
|
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.
|
54
|
+
!votes.empty?
|
60
55
|
end
|
61
56
|
|
62
|
-
def voted_up_on?
|
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.
|
60
|
+
!votes.empty?
|
66
61
|
end
|
67
62
|
|
68
|
-
def voted_down_on?
|
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.
|
66
|
+
!votes.empty?
|
72
67
|
end
|
73
68
|
|
74
|
-
def voted_as_when_voting_on
|
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
|
-
|
71
|
+
:vote_scope => args[:vote_scope]).select(:vote_flag).last
|
77
72
|
return nil unless vote
|
78
|
-
|
73
|
+
vote.vote_flag
|
79
74
|
end
|
80
75
|
|
81
|
-
def find_votes
|
76
|
+
def find_votes(extra_conditions = {})
|
82
77
|
votes.where(extra_conditions)
|
83
78
|
end
|
84
79
|
|
85
|
-
def find_up_votes
|
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
|
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
|
94
|
-
find_votes extra_conditions.merge(
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
-
:
|
120
|
-
:
|
121
|
-
:
|
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
|
@@ -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
|
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
|
-
|
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, :
|
19
|
+
JSON.parse(json, symbolize_names: true)
|
21
20
|
end
|
22
21
|
end
|
23
22
|
end
|
24
|
-
end
|
23
|
+
end
|
data/lib/redmine_crm/currency.rb
CHANGED
@@ -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,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
|