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
metadata CHANGED
@@ -1,17 +1,101 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: redmine_crm
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.23
4
+ version: 0.0.53
5
5
  platform: ruby
6
6
  authors:
7
- - RedmineCRM
7
+ - RedmineUP
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-09-28 00:00:00.000000000 Z
12
- dependencies: []
13
- description: Common libraries for RedmineCRM plugins for Redmine. Requered Redmine
14
- from http://redmine.org
11
+ date: 2020-04-07 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: liquid
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "<"
32
+ - !ruby/object:Gem::Version
33
+ version: 2.6.4
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "<"
39
+ - !ruby/object:Gem::Version
40
+ version: 2.6.4
41
+ - !ruby/object:Gem::Dependency
42
+ name: rubyzip
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: sqlite3
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: mysql2
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: pg
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ description: Common libraries for RedmineUP plugins (www.redmineup.com) for Redmine.
98
+ Requered Redmine from http://redmine.org
15
99
  email:
16
100
  - support@redminecrm.com
17
101
  executables: []
@@ -22,56 +106,106 @@ files:
22
106
  - Gemfile
23
107
  - README.md
24
108
  - Rakefile
109
+ - app/controllers/redmine_crm_controller.rb
110
+ - app/views/redmine_crm/_money.html.erb
111
+ - app/views/redmine_crm/settings.html.erb
112
+ - bitbucket-pipelines.yml
25
113
  - config/currency_iso.json
114
+ - config/locales/en.yml
115
+ - config/locales/ru.yml
116
+ - config/routes.rb
26
117
  - doc/CHANGELOG
27
118
  - doc/LICENSE.txt
28
119
  - lib/redmine_crm.rb
120
+ - lib/redmine_crm/acts_as_draftable/draft.rb
121
+ - lib/redmine_crm/acts_as_draftable/rcrm_acts_as_draftable.rb
122
+ - lib/redmine_crm/acts_as_list/list.rb
123
+ - lib/redmine_crm/acts_as_taggable/rcrm_acts_as_taggable.rb
124
+ - lib/redmine_crm/acts_as_taggable/tag.rb
125
+ - lib/redmine_crm/acts_as_taggable/tag_list.rb
126
+ - lib/redmine_crm/acts_as_taggable/tagging.rb
127
+ - lib/redmine_crm/acts_as_viewed/rcrm_acts_as_viewed.rb
128
+ - lib/redmine_crm/acts_as_votable/rcrm_acts_as_votable.rb
129
+ - lib/redmine_crm/acts_as_votable/rcrm_acts_as_voter.rb
130
+ - lib/redmine_crm/acts_as_votable/votable.rb
131
+ - lib/redmine_crm/acts_as_votable/vote.rb
132
+ - lib/redmine_crm/acts_as_votable/voter.rb
133
+ - lib/redmine_crm/assets_manager.rb
134
+ - lib/redmine_crm/colors_helper.rb
135
+ - lib/redmine_crm/compatibility/application_controller_patch.rb
29
136
  - lib/redmine_crm/currency.rb
30
137
  - lib/redmine_crm/currency/formatting.rb
31
138
  - lib/redmine_crm/currency/heuristics.rb
32
139
  - lib/redmine_crm/currency/loader.rb
140
+ - lib/redmine_crm/engine.rb
141
+ - lib/redmine_crm/helpers/external_assets_helper.rb
142
+ - lib/redmine_crm/helpers/form_tag_helper.rb
33
143
  - lib/redmine_crm/helpers/tags_helper.rb
34
144
  - lib/redmine_crm/helpers/vote_helper.rb
145
+ - lib/redmine_crm/hooks/views_layouts_hook.rb
146
+ - lib/redmine_crm/liquid/drops/issues_drop.rb
147
+ - lib/redmine_crm/liquid/drops/news_drop.rb
148
+ - lib/redmine_crm/liquid/drops/projects_drop.rb
149
+ - lib/redmine_crm/liquid/drops/time_entries_drop.rb
150
+ - lib/redmine_crm/liquid/drops/users_drop.rb
151
+ - lib/redmine_crm/liquid/filters/arrays.rb
152
+ - lib/redmine_crm/liquid/filters/base.rb
153
+ - lib/redmine_crm/liquid/filters/colors.rb
35
154
  - lib/redmine_crm/money_helper.rb
36
- - lib/redmine_crm/rcrm_acts_as_taggable.rb
37
- - lib/redmine_crm/rcrm_acts_as_viewed.rb
38
- - lib/redmine_crm/rcrm_acts_as_votable.rb
39
- - lib/redmine_crm/rcrm_acts_as_voter.rb
40
- - lib/redmine_crm/tag.rb
41
- - lib/redmine_crm/tag_list.rb
42
- - lib/redmine_crm/tagging.rb
155
+ - lib/redmine_crm/settings.rb
156
+ - lib/redmine_crm/settings/money.rb
43
157
  - lib/redmine_crm/version.rb
44
- - lib/redmine_crm/votable.rb
45
- - lib/redmine_crm/vote.rb
46
- - lib/redmine_crm/voter.rb
47
158
  - redmine_crm.gemspec
48
- - test/acts_as_taggable_test.rb
159
+ - test/acts_as_draftable/draft_test.rb
160
+ - test/acts_as_draftable/rcrm_acts_as_draftable_test.rb
161
+ - test/acts_as_taggable/rcrm_acts_as_taggable_test.rb
162
+ - test/acts_as_taggable/tag_list_test.rb
163
+ - test/acts_as_taggable/tag_test.rb
164
+ - test/acts_as_taggable/tagging_test.rb
165
+ - test/acts_as_viewed/rcrm_acts_as_viewed_test.rb
166
+ - test/acts_as_votable/rcrm_acts_as_votable_test.rb
167
+ - test/acts_as_votable/rcrm_acts_as_voter_test.rb
168
+ - test/acts_as_votable/votable_test.rb
169
+ - test/acts_as_votable/voter_test.rb
49
170
  - test/currency_test.rb
50
171
  - test/database.yml
51
- - test/fixtures/issue.rb
52
172
  - test/fixtures/issues.yml
173
+ - test/fixtures/news.yml
174
+ - test/fixtures/projects.yml
53
175
  - test/fixtures/taggings.yml
54
176
  - test/fixtures/tags.yml
55
- - test/fixtures/user.rb
56
177
  - test/fixtures/users.yml
57
178
  - test/fixtures/votable_caches.yml
58
179
  - test/fixtures/votables.yml
59
- - test/fixtures/vote_classes.rb
60
180
  - test/fixtures/voters.yml
181
+ - test/liquid/drops/issues_drop_test.rb
182
+ - test/liquid/drops/news_drop_test.rb
183
+ - test/liquid/drops/projects_drop_test.rb
184
+ - test/liquid/drops/uses_drop_test.rb
185
+ - test/liquid/filters/arrays_filter_test.rb
186
+ - test/liquid/filters/base_filter_test.rb
187
+ - test/liquid/filters/colors_filter_test.rb
188
+ - test/liquid/liquid_helper.rb
189
+ - test/models/issue.rb
190
+ - test/models/news.rb
191
+ - test/models/project.rb
192
+ - test/models/user.rb
193
+ - test/models/vote_classes.rb
61
194
  - test/money_helper_test.rb
62
195
  - test/schema.rb
63
- - test/tag_test.rb
64
- - test/tagging_test.rb
65
196
  - test/tags_helper_test.rb
66
197
  - test/test_helper.rb
67
- - test/viewed_test.rb
68
- - test/votable_model_test.rb
69
- - test/votable_test.rb
70
198
  - test/vote_helper_test.rb
71
- - test/voter_model_test.rb
72
- homepage: ''
199
+ - vendor/assets/images/money.png
200
+ - vendor/assets/images/vcard.png
201
+ - vendor/assets/javascripts/Chart.bundle.min.js
202
+ - vendor/assets/javascripts/select2.js
203
+ - vendor/assets/javascripts/select2_helpers.js
204
+ - vendor/assets/stylesheets/money.css
205
+ - vendor/assets/stylesheets/select2.css
206
+ homepage: https://www.redmineup.com
73
207
  licenses:
74
- - GPL2
208
+ - GPL-2.0
75
209
  metadata: {}
76
210
  post_install_message:
77
211
  rdoc_options: []
@@ -89,32 +223,48 @@ required_rubygems_version: !ruby/object:Gem::Requirement
89
223
  version: '0'
90
224
  requirements: []
91
225
  rubyforge_project:
92
- rubygems_version: 2.4.8
226
+ rubygems_version: 2.6.11
93
227
  signing_key:
94
228
  specification_version: 4
95
- summary: Common libraries for RedmineCRM plugins for Redmine
229
+ summary: Common libraries for RedmineUP plugins for Redmine
96
230
  test_files:
97
- - test/acts_as_taggable_test.rb
231
+ - test/acts_as_draftable/draft_test.rb
232
+ - test/acts_as_draftable/rcrm_acts_as_draftable_test.rb
233
+ - test/acts_as_taggable/rcrm_acts_as_taggable_test.rb
234
+ - test/acts_as_taggable/tag_list_test.rb
235
+ - test/acts_as_taggable/tag_test.rb
236
+ - test/acts_as_taggable/tagging_test.rb
237
+ - test/acts_as_viewed/rcrm_acts_as_viewed_test.rb
238
+ - test/acts_as_votable/rcrm_acts_as_votable_test.rb
239
+ - test/acts_as_votable/rcrm_acts_as_voter_test.rb
240
+ - test/acts_as_votable/votable_test.rb
241
+ - test/acts_as_votable/voter_test.rb
98
242
  - test/currency_test.rb
99
243
  - test/database.yml
100
- - test/fixtures/issue.rb
101
244
  - test/fixtures/issues.yml
245
+ - test/fixtures/news.yml
246
+ - test/fixtures/projects.yml
102
247
  - test/fixtures/taggings.yml
103
248
  - test/fixtures/tags.yml
104
- - test/fixtures/user.rb
105
249
  - test/fixtures/users.yml
106
250
  - test/fixtures/votable_caches.yml
107
251
  - test/fixtures/votables.yml
108
- - test/fixtures/vote_classes.rb
109
252
  - test/fixtures/voters.yml
253
+ - test/liquid/drops/issues_drop_test.rb
254
+ - test/liquid/drops/news_drop_test.rb
255
+ - test/liquid/drops/projects_drop_test.rb
256
+ - test/liquid/drops/uses_drop_test.rb
257
+ - test/liquid/filters/arrays_filter_test.rb
258
+ - test/liquid/filters/base_filter_test.rb
259
+ - test/liquid/filters/colors_filter_test.rb
260
+ - test/liquid/liquid_helper.rb
261
+ - test/models/issue.rb
262
+ - test/models/news.rb
263
+ - test/models/project.rb
264
+ - test/models/user.rb
265
+ - test/models/vote_classes.rb
110
266
  - test/money_helper_test.rb
111
267
  - test/schema.rb
112
- - test/tag_test.rb
113
- - test/tagging_test.rb
114
268
  - test/tags_helper_test.rb
115
269
  - test/test_helper.rb
116
- - test/viewed_test.rb
117
- - test/votable_model_test.rb
118
- - test/votable_test.rb
119
270
  - test/vote_helper_test.rb
120
- - test/voter_model_test.rb
@@ -1,287 +0,0 @@
1
- # Copyright (c) 2008 Damian Martinelli
2
- #
3
- # Permission is hereby granted, free of charge, to any person obtaining
4
- # a copy of this software and associated documentation files (the
5
- # "Software"), to deal in the Software without restriction, including
6
- # without limitation the rights to use, copy, modify, merge, publish,
7
- # distribute, sublicense, and/or sell copies of the Software, and to
8
- # permit persons to whom the Software is furnished to do so, subject to
9
- # the following conditions:
10
- #
11
- # The above copyright notice and this permission notice shall be
12
- # included in all copies or substantial portions of the Software.
13
- #
14
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
- # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
- # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
- # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
- # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
- # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
- # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
- module RedmineCrm
22
- module ActiveRecord #:nodoc:
23
- module Acts #:nodoc:
24
-
25
- # == acts_as_viewed
26
- # Adds views count capabilities to any ActiveRecord object.
27
- # It has the ability to work with objects that have or don't special fields to keep a tally of the
28
- # viewings for each object.
29
- # In addition it will by default use the User model as the viewer object and keep the viewings per-user.
30
- # It can be configured to use another class.
31
- # The IP address are used to not repeat views from the same ip. Only one view are count by user or IP.
32
- #
33
- # Special methods are provided to create the viewings table and if needed, to add the special fields needed
34
- # to keep per-objects viewings fast for access to viewed objects. Can be easily used in migrations.
35
- #
36
- # == Example of usage:
37
- #
38
- # class Video < ActiveRecord::Base
39
- # acts_as_viewed
40
- # end
41
- #
42
- # In a controller:
43
- #
44
- # bill = User.find_by_name 'bill'
45
- # batman = Video.find_by_title 'Batman'
46
- # toystory = Video.find_by_title 'Toy Story'
47
- #
48
- # batman.view request.remote_addr, bill
49
- # toystory.view request.remote_addr, bill
50
- #
51
- # batman.view_count # => 1
52
- #
53
- #
54
- module Viewed
55
-
56
- class ViewedError < RuntimeError; end
57
-
58
- def self.included(base) #:nodoc:
59
- base.extend(ClassMethods)
60
- end
61
-
62
- module ClassMethods
63
-
64
- # Make the model viewable.
65
- # The Viewing model, holding the details of the viewings, will be created dynamically if it doesn't exist.
66
- #
67
- # * Adds a <tt>has_many :viewings</tt> association to the model for easy retrieval of the detailed viewings.
68
- # * Adds a <tt>has_many :viewers</tt> association to the object.
69
- # * Adds a <tt>has_many :viewings</tt> associations to the viewer class.
70
- #
71
- # === Options
72
- # * <tt>:viewing_class</tt> -
73
- # class of the model used for the viewings. Defaults to Viewing. This class will be dynamically created if not already defined.
74
- # If the class is predefined, it must have in it the following definitions:
75
- # <tt>belongs_to :viewed, :polymorphic => true</tt>
76
- # <tt>belongs_to :viewer, :class_name => 'User', :foreign_key => :viewer_id</tt> replace user with the viewer class if needed.
77
- # * <tt>:viewer_class</tt> -
78
- # class of the model that creates the viewing.
79
- # Defaults to User This class will NOT be created, so it must be defined in the app.
80
- # Use the IP address to prevent multiple viewings from the same client.
81
- #
82
- def rcrm_acts_as_viewed(options = {})
83
- # don't allow multiple calls
84
- return if self.included_modules.include?(ActiveRecord::Acts::Viewed::ViewMethods)
85
- send :include, ActiveRecord::Acts::Viewed::ViewMethods
86
-
87
- # Create the model for ratings if it doesn't yet exist
88
- viewing_class = options[:viewing_class] || 'Viewing'
89
- viewer_class = options[:viewer_class] || 'User'
90
-
91
- unless Object.const_defined?(viewing_class)
92
- Object.class_eval <<-EOV
93
- class #{viewing_class} < ActiveRecord::Base
94
- belongs_to :viewed, :polymorphic => true
95
- belongs_to :viewer, :class_name => #{viewer_class}, :foreign_key => :viewer_id
96
- end
97
- EOV
98
- end
99
-
100
- # Rails < 3
101
- # write_inheritable_attribute( :acts_as_viewed_options ,
102
- # { :viewing_class => viewing_class,
103
- # :viewer_class => viewer_class } )
104
- # class_inheritable_reader :acts_as_viewed_options
105
-
106
- # Rails >= 3
107
- class_attribute :acts_as_viewed_options
108
- self.acts_as_viewed_options = { :viewing_class => viewing_class,
109
- :viewer_class => viewer_class }
110
- class_eval do
111
- has_many :viewings, :as => :viewed, :dependent => :delete_all, :class_name => viewing_class.to_s
112
- has_many(:viewers, :through => :viewings, :class_name => viewer_class.to_s)
113
-
114
- before_create :init_viewing_fields
115
- end
116
-
117
- # Add to the User (or whatever the viewer is) a has_many viewings
118
- viewer_as_class = viewer_class.constantize
119
- return if viewer_as_class.instance_methods.include?('find_in_viewings')
120
- viewer_as_class.class_eval <<-EOS
121
- has_many :viewings, :foreign_key => :viewer_id, :class_name => #{viewing_class.to_s}
122
- EOS
123
- end
124
- end
125
-
126
- module ViewMethods
127
-
128
- def self.included(base) #:nodoc:
129
- base.extend ClassMethods
130
- end
131
-
132
- # Is this object viewed already?
133
- def viewed?
134
- return (!self.views.nil? && self.views > 0) if attributes.has_key? 'views'
135
- !viewings.first.nil?
136
- end
137
-
138
- # Get the number of viewings for this object based on the views field,
139
- # or with a SQL query if the viewed objects doesn't have the views field
140
- def view_count
141
- return ("#{self.total_views}(#{self.views})" || 0) if attributes.has_key? 'views'
142
- viewings.count
143
- end
144
-
145
- # Change views count (total_views and views) if it's existing in object
146
- # If options[:only_total] == true count of unique views doesn't change
147
- def increase_views_count(options)
148
- if attributes.has_key?('views') && attributes.has_key?('total_views')
149
- target = self
150
- target.views = ( (target.views || 0) + 1 ) if !options[:only_total]
151
- target.total_views = ( (target.total_views || 0) + 1)
152
- target.save(:validate => false)
153
- # target.save_without_validation
154
- end
155
- end
156
-
157
- # View the object with or without a viewer - create new or update as needed
158
- #
159
- # * <tt>ip</tt> - the viewer ip
160
- # * <tt>viewer</tt> - an object of the viewer class. Must be valid and with an id to be used. Or nil
161
- def view ip, viewer = nil
162
- # Sanity checks for the parameters
163
- viewing_class = acts_as_viewed_options[:viewing_class].constantize
164
- if viewer && !(acts_as_viewed_options[:viewer_class].constantize === viewer)
165
- raise ViewedError, "the viewer object must be the one used when defining acts_as_viewed (or a descendent of it). other objects are not acceptable"
166
- end
167
-
168
- viewing_class.transaction do
169
- if !viewed_by? ip, viewer
170
- view = viewing_class.new
171
- view.viewer_id = viewer.id if viewer && !viewer.id.nil?
172
- view.ip = ip
173
- viewings << view
174
- view.save
175
- increase_views_count(:only_total => false)
176
- else
177
- increase_views_count(:only_total => true)
178
- end
179
- true
180
- end
181
- end
182
-
183
- # Check if an item was already viewed by the given viewer
184
- def viewed_by? ip, viewer = nil
185
- if viewer && !viewer.nil? && !(acts_as_viewed_options[:viewer_class].constantize === viewer)
186
- raise ViewedError, "the viewer object must be the one used when defining acts_as_viewed (or a descendent of it). other objects are not acceptable"
187
- end
188
- if viewer && !viewer.id.nil? && !viewer.anonymous?
189
- return viewings.where("viewer_id = '#{viewer.id}'").any?
190
- else
191
- return viewings.where("ip = '#{ip}'").any?
192
- end
193
- end
194
-
195
- private
196
-
197
- def init_viewing_fields #:nodoc:
198
- if attributes.has_key? 'views'
199
- self.views ||= 0
200
- end
201
- end
202
-
203
- end
204
-
205
- module ClassMethods
206
-
207
- # Generate the viewings columns on a table, to be used when creating the table
208
- # in a migration. This is the preferred way to do in a migration that creates
209
- # new tables as it will make it as part of the table creation, and not generate
210
- # ALTER TABLE calls after the fact
211
- def generate_viewings_columns table
212
- table.column :views, :integer #uniq views
213
- table.column :total_views, :integer
214
- end
215
-
216
- # Create the needed columns for acts_as_viewed.
217
- # To be used during migration, but can also be used in other places.
218
- def add_viewings_columns
219
- if !self.content_columns.find { |c| 'views' == c.name }
220
- self.connection.add_column table_name, :views, :integer, :default => '0'
221
- self.connection.add_column table_name, :total_views, :integer, :default => '0'
222
- self.reset_column_information
223
- end
224
- end
225
-
226
- # Remove the acts_as_viewed specific columns added with add_viewings_columns
227
- # To be used during migration, but can also be used in other places
228
- def remove_viewings_columns
229
- if self.content_columns.find { |c| 'views' == c.name }
230
- self.connection.remove_column table_name, :views
231
- self.connection.remove_column table_name, :total_views
232
- self.reset_column_information
233
- end
234
- end
235
-
236
- # Create the viewings table
237
- # === Options hash:
238
- # * <tt>:table_name</tt> - use a table name other than viewings
239
- # To be used during migration, but can also be used in other places
240
- def create_viewings_table options = {}
241
- name = options[:table_name] || :viewings
242
- if !self.connection.table_exists?(name)
243
- self.connection.create_table(name) do |t|
244
- t.column :viewer_id, :integer
245
- t.column :viewed_id, :integer
246
- t.column :viewed_type, :string
247
- t.column :ip, :string, :limit => '24'
248
- t.column :created_at, :datetime
249
- end
250
-
251
- self.connection.add_index(name, :viewer_id)
252
- self.connection.add_index(name, [:viewed_type, :viewed_id])
253
- end
254
- end
255
-
256
- # Drop the viewings table.
257
- # === Options hash:
258
- # * <tt>:table_name</tt> - the name of the viewings table, defaults to viewings
259
- # To be used during migration, but can also be used in other places
260
- def drop_viewings_table options = {}
261
- name = options[:table_name] || :viewings
262
- if self.connection.table_exists?(name)
263
- self.connection.drop_table(name)
264
- end
265
- end
266
-
267
- # Find all viewings for a specific viewer.
268
- def find_viewed_by viewer
269
- viewing_class = acts_as_viewed_options[:viewing_class].constantize
270
- if !(acts_as_viewed_options[:viewer_class].constantize === viewer)
271
- raise ViewedError, "The viewer object must be the one used when defining acts_as_viewed (or a descendent of it). other objects are not acceptable"
272
- end
273
- raise ViewedError, "Viewer must be a valid and existing object" if viewer.nil? || viewer.id.nil?
274
- raise ViewedError, 'Viewer must be a valid viewer' if !viewing_class.column_names.include? "viewer_id"
275
- viewed_class = ActiveRecord::Base.send(:class_name_of_active_record_descendant, self).to_s
276
- conds = [ 'viewed_type = ? AND viewer_id = ?', viewed_class, viewer.id ]
277
- acts_as_viewed_options[:viewing_class].constantize.find(:all, :conditions => conds).collect {|r| r.viewed_type.constantize.find_by_id r.viewed.id }
278
- end
279
- end
280
- end
281
- end
282
- end
283
- end
284
-
285
-
286
- ActiveRecord::Base.send :include, RedmineCrm::ActiveRecord::Acts::Viewed
287
-
@@ -1,27 +0,0 @@
1
- module RedmineCrm
2
- module ActsAsVotable
3
- # module Extenders
4
-
5
- module Voter
6
-
7
- def voter?
8
- false
9
- end
10
-
11
- def rcrm_acts_as_voter(*args)
12
- # byebug
13
- require 'redmine_crm/voter'
14
- include ActsAsVotable::Voter
15
-
16
- class_eval do
17
- def self.voter?
18
- true
19
- end
20
- end
21
-
22
- end
23
-
24
- end
25
- # end
26
- end
27
- end
@@ -1,81 +0,0 @@
1
- module RedmineCrm
2
- class Tag < ActiveRecord::Base
3
- has_many :taggings, :dependent => :destroy
4
-
5
- validates_presence_of :name
6
- # validates_uniqueness_of :name
7
- validates :name, :uniqueness => { :message => " not uniq tag" }
8
- validates :name, :presence => true
9
- cattr_accessor :destroy_unused
10
- self.destroy_unused = false
11
-
12
- attr_accessible :name if defined?(ActiveModel::MassAssignmentSecurity)
13
-
14
- # LIKE is used for cross-database case-insensitivity
15
- def self.find_or_create_with_like_by_name(name)
16
- # find(:first, :conditions => ["name LIKE ?", name]) || create(:name => name)
17
- where("LOWER(name) LIKE LOWER(?)", name).first || create(:name => name)
18
- end
19
-
20
- def ==(object)
21
- super || (object.is_a?(Tag) && name == object.name)
22
- end
23
-
24
- def to_s
25
- name
26
- end
27
-
28
- def count
29
- read_attribute(:count).to_i
30
- end
31
-
32
- class << self
33
- # Calculate the tag counts for all tags.
34
- # :start_at - Restrict the tags to those created after a certain time
35
- # :end_at - Restrict the tags to those created before a certain time
36
- # :conditions - A piece of SQL conditions to add to the query
37
- # :limit - The maximum number of tags to return
38
- # :order - A piece of SQL to order by. Eg 'count desc' or 'taggings.created_at desc'
39
- # :at_least - Exclude tags with a frequency less than the given value
40
- # :at_most - Exclude tags with a frequency greater than the given value
41
- def counts(options = {})
42
- # find(:all, options_for_counts(options))
43
- opt = options_for_counts(options)
44
- select(opt[:select]).where(opt[:conditions]).joins(opt[:joins]).group(opt[:group])
45
- end
46
-
47
- def options_for_counts(options = {})
48
- options.assert_valid_keys :start_at, :end_at, :conditions, :at_least, :at_most, :order, :limit, :joins
49
- options = options.dup
50
-
51
- start_at = sanitize_sql(["#{Tagging.table_name}.created_at >= ?", options.delete(:start_at)]) if options[:start_at]
52
- end_at = sanitize_sql(["#{Tagging.table_name}.created_at <= ?", options.delete(:end_at)]) if options[:end_at]
53
-
54
- conditions = [
55
- (sanitize_sql(options.delete(:conditions)) if options[:conditions]),
56
- start_at,
57
- end_at
58
- ].compact
59
-
60
- conditions = conditions.join(' AND ') if conditions.any?
61
-
62
- joins = ["INNER JOIN #{Tagging.table_name} ON #{Tag.table_name}.id = #{Tagging.table_name}.tag_id"]
63
- joins << options.delete(:joins) if options[:joins]
64
-
65
- at_least = sanitize_sql(['COUNT(*) >= ?', options.delete(:at_least)]) if options[:at_least]
66
- at_most = sanitize_sql(['COUNT(*) <= ?', options.delete(:at_most)]) if options[:at_most]
67
- having = "COUNT(*) > 0"
68
- having = [having, at_least, at_most].compact.join(' AND ')
69
- group_by = "#{Tag.table_name}.id, #{Tag.table_name}.name"
70
- # group_by << " AND #{having}" unless having.blank?
71
-
72
- { :select => "#{Tag.table_name}.id, #{Tag.table_name}.name, COUNT(*) AS count",
73
- :joins => joins.join(" "),
74
- :conditions => conditions,
75
- :group => group_by,
76
- :having => having
77
- }.update(options)
78
- end
79
- end
80
- end
81
- end