redmine_crm 0.0.23 → 0.0.43
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 +4 -4
- data/.gitignore +4 -1
- data/Gemfile +1 -1
- data/README.md +166 -33
- data/Rakefile +3 -12
- data/bitbucket-pipelines.yml +42 -0
- data/config/currency_iso.json +12 -0
- data/doc/CHANGELOG +81 -2
- data/lib/redmine_crm/acts_as_draftable/draft.rb +40 -0
- data/lib/redmine_crm/acts_as_draftable/rcrm_acts_as_draftable.rb +170 -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} +105 -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 +0 -3
- data/lib/redmine_crm/currency/heuristics.rb +1 -1
- data/lib/redmine_crm/currency/loader.rb +5 -6
- 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/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 +2 -4
- data/lib/redmine_crm/version.rb +1 -1
- data/lib/redmine_crm.rb +56 -21
- data/redmine_crm.gemspec +9 -4
- data/test/acts_as_draftable/draft_test.rb +29 -0
- data/test/acts_as_draftable/rcrm_acts_as_draftable_test.rb +179 -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/vcard.png +0 -0
- data/vendor/assets/javascripts/Chart.bundle.min.js +16 -0
- data/vendor/assets/javascripts/select2.js +3 -0
- data/vendor/assets/javascripts/select2_helpers.js +186 -0
- data/vendor/assets/stylesheets/select2.css +414 -0
- metadata +162 -38
- 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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c7ec4763f7c0ff9e5ce0744bcd8579020ed89b32
|
4
|
+
data.tar.gz: 45d4f87a91b17c299097c1f6aa5a9732507f30cc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a604d13c92a5a5e47ff93d7aeb3867c503c1743beb55059502cbc4fd28a2ddadac9e6cc7745e950249aace899dab2ed8e86d7ced27d5682bd2aade9f7c6e6ca3
|
7
|
+
data.tar.gz: d26992ff800bf72702248dd3d3afb416ee15a5432091ed38befa56196a436b75901fc04a328dc742450261d1e59dba55552e33c8a32e985e6834fada408c79dc
|
data/.gitignore
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,71 +1,204 @@
|
|
1
1
|
# RedmineCrm
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
* rcrm_acts_as_viewable
|
3
|
+
This gem is used at RedmineUP as a general place for shared functionality and
|
4
|
+
assets. It contains **Chart.js** and **select2** JS libraries, various mixins
|
5
|
+
for ActiveRecord models and other things you might find useful.
|
7
6
|
|
8
|
-
|
7
|
+
Among mixins there are:
|
8
|
+
|
9
|
+
* rcrm_acts_as_draftable
|
10
|
+
* rcrm_acts_as_taggable
|
11
|
+
* rcrm_acts_as_viewable
|
12
|
+
* rcrm_acts_as_votable
|
9
13
|
|
10
|
-
Add this line to your application's Gemfile:
|
11
14
|
|
15
|
+
## Installation
|
16
|
+
|
17
|
+
Add it to your plugin's Gemfile:
|
12
18
|
```ruby
|
13
|
-
gem
|
19
|
+
gem 'redmine_crm'
|
20
|
+
```
|
21
|
+
|
22
|
+
Then invoke the following command in your plugin's or Redmine directory:
|
23
|
+
```
|
24
|
+
$ bundle install
|
14
25
|
```
|
15
26
|
|
16
|
-
And
|
27
|
+
And now you can start using it.
|
17
28
|
|
18
|
-
$ bundle
|
19
29
|
|
20
|
-
|
30
|
+
## Usage
|
31
|
+
### Drafts
|
32
|
+
This module allows saving and restoring drafts for different models. To be
|
33
|
+
saved as a draft, an instance does not need to pass the validations. Drafts
|
34
|
+
store not only model attributes, but also associations and virtual attributes.
|
35
|
+
A draft could be linked to a given user, so every user can manage his/her own
|
36
|
+
drafts independent of others. A draft might have a parent instance.
|
37
|
+
|
38
|
+
First of all, drafts need to be saved somewhere, so let's create a migration:
|
39
|
+
```ruby
|
40
|
+
class CreateDrafts < Rails.version > '5' ? ActiveRecord::Migration[5.0] : ActiveRecord::Migration
|
41
|
+
def change
|
42
|
+
ActiveRecord::Base.create_drafts_table
|
43
|
+
end
|
44
|
+
end
|
45
|
+
```
|
46
|
+
|
47
|
+
Then in the Redmine directory run:
|
48
|
+
```
|
49
|
+
$ rake redmine:plugins:migrate
|
50
|
+
```
|
21
51
|
|
22
|
-
|
52
|
+
Next, add `rcrm_acts_as_draftable` to a model for which you want to save drafts:
|
53
|
+
```ruby
|
54
|
+
class Message < ActiveRecord::Base
|
55
|
+
rcrm_acts_as_draftable
|
56
|
+
end
|
57
|
+
```
|
23
58
|
|
24
|
-
|
59
|
+
And that's it for the preparation, now you're ready to make use of drafts:
|
25
60
|
```ruby
|
26
|
-
|
61
|
+
# You can save message as a draft.
|
62
|
+
Message.new(subject: 'foo').save_draft
|
63
|
+
|
64
|
+
# And later restore message from the draft.
|
65
|
+
draft = Message.drafts(nil).last
|
66
|
+
message = draft.restore
|
67
|
+
puts message.subject
|
68
|
+
# => foo
|
69
|
+
|
70
|
+
# Draft can be overwritten.
|
71
|
+
message.content = 'bar'
|
72
|
+
puts message.save_draft
|
73
|
+
# => true
|
74
|
+
|
75
|
+
# You can also save draft linked to a particular user.
|
76
|
+
Message.new(subject: 'baz').save_draft(user: current_user)
|
77
|
+
|
78
|
+
# And restore message from some user's draft.
|
79
|
+
user_draft = Message.drafts(current_user).last
|
80
|
+
user_message = user_draft.restore
|
81
|
+
puts user_message.subject
|
82
|
+
# => baz
|
83
|
+
|
84
|
+
# It's also possible to restore a bunch of messages at once.
|
85
|
+
messages = Message.drafts(current_user).restore_all
|
86
|
+
p messages.map(&:subject)
|
87
|
+
# => ["baz"]
|
88
|
+
|
89
|
+
# When a model instance is saved, corresponding draft is removed.
|
90
|
+
puts Message.drafts(current_user).count
|
91
|
+
# => 1
|
92
|
+
user_message.board_id = Board.first.id
|
93
|
+
user_message.save!
|
94
|
+
puts Message.drafts(current_user).count
|
95
|
+
# => 0
|
96
|
+
|
97
|
+
# Drafts will be saved only for new (not persisted) or changed instances.
|
98
|
+
puts Message.new.save_draft
|
99
|
+
# => true
|
100
|
+
persisted = Message.last
|
101
|
+
puts persisted.save_draft
|
102
|
+
# => false
|
103
|
+
persisted.subject = 'other subject'
|
104
|
+
puts persisted.save_draft
|
105
|
+
# => true
|
106
|
+
```
|
27
107
|
|
28
|
-
|
29
|
-
|
30
|
-
end
|
108
|
+
### Tags
|
109
|
+
This module makes it possible to tag objects.
|
31
110
|
|
32
|
-
|
33
|
-
|
111
|
+
First, create a migration:
|
112
|
+
```ruby
|
113
|
+
class CreateTags < Rails.version > '5' ? ActiveRecord::Migration[5.0] : ActiveRecord::Migration
|
114
|
+
def change
|
115
|
+
ActiveRecord::Base.create_taggable_table
|
34
116
|
end
|
35
117
|
end
|
36
118
|
```
|
37
|
-
For rcrm_acts_as_viewed You may add column for your model
|
38
|
-
with help:
|
39
119
|
|
120
|
+
Then in the Redmine directory run:
|
121
|
+
```
|
122
|
+
$ rake redmine:plugins:migrate
|
123
|
+
```
|
124
|
+
|
125
|
+
Next, add `rcrm_acts_as_taggable` to a model for which you want to provide tags:
|
40
126
|
```ruby
|
127
|
+
class Contact < ActiveRecord::Base
|
128
|
+
rcrm_acts_as_taggable
|
129
|
+
end
|
130
|
+
```
|
41
131
|
|
42
|
-
|
132
|
+
TODO: Add examples of usage.
|
43
133
|
|
44
|
-
|
45
|
-
|
46
|
-
and view_count will return two number: total view and unique views.
|
47
|
-
Without this migration you will get only unique views.
|
134
|
+
### Viewings
|
135
|
+
This module allows you to count views for some ActiveRecord model instances.
|
48
136
|
|
49
|
-
|
137
|
+
To count views you'll need to create a migration:
|
138
|
+
```ruby
|
139
|
+
class CreateViewings < Rails.version > '5' ? ActiveRecord::Migration[5.0] : ActiveRecord::Migration
|
140
|
+
def change
|
141
|
+
ActiveRecord::Base.create_viewings_table
|
142
|
+
end
|
143
|
+
end
|
144
|
+
```
|
50
145
|
|
146
|
+
To apply it, run the following in the Redmine directory:
|
51
147
|
```
|
52
|
-
rake redmine:plugins:migrate
|
148
|
+
$ rake redmine:plugins:migrate
|
53
149
|
```
|
54
150
|
|
55
|
-
|
151
|
+
Then add `rcrm_acts_as_viewed` to a model for which you want to count views.
|
152
|
+
```ruby
|
153
|
+
class Question < ActiveRecord::Base
|
154
|
+
rcrm_acts_as_viewed
|
155
|
+
end
|
156
|
+
```
|
157
|
+
|
158
|
+
TODO: Provide some usage examples.
|
56
159
|
|
57
|
-
|
160
|
+
### Votes
|
161
|
+
With this module you can make your models votable and allow users to vote.
|
58
162
|
|
163
|
+
As always, create a migration first:
|
59
164
|
```ruby
|
60
|
-
|
165
|
+
class CreateVotes < Rails.version > '5' ? ActiveRecord::Migration[5.0] : ActiveRecord::Migration
|
166
|
+
def change
|
167
|
+
ActiveRecord::Base.create_votable_table
|
168
|
+
end
|
169
|
+
end
|
170
|
+
```
|
171
|
+
|
172
|
+
Then apply it by running the following command in the Redmine directory:
|
173
|
+
```
|
174
|
+
$ rake redmine:plugins:migrate
|
175
|
+
```
|
176
|
+
|
177
|
+
To make a model votable, add `rcrm_acts_as_votable` to it:
|
178
|
+
```ruby
|
179
|
+
class Question < ActiveRecord::Base
|
61
180
|
rcrm_acts_as_votable
|
181
|
+
end
|
62
182
|
```
|
63
183
|
|
184
|
+
TODO: Write about `rcrm_acts_as_voter` and add usage examples.
|
64
185
|
|
65
|
-
## Run test
|
66
186
|
|
187
|
+
## Development
|
188
|
+
|
189
|
+
If you're planning to extend this gem, you will need to install development
|
190
|
+
dependencies. To do this, execute the following command in the project's
|
191
|
+
directory:
|
192
|
+
```
|
193
|
+
$ bundle install
|
194
|
+
```
|
195
|
+
|
196
|
+
After that you'll be able to run tests:
|
67
197
|
```
|
68
|
-
|
198
|
+
$ bundle exec rake test
|
69
199
|
```
|
70
200
|
|
71
|
-
|
201
|
+
SQLite in-memory database will be used by default, which is the fastest way to run tests. To run them using different database adapters, set `DB` environment variable to one of the available values — `mysql`, `postgresql`, `sqlite`. For example, to use PostgreSQL, invoke tests like so:
|
202
|
+
```
|
203
|
+
$ bundle exec rake test DB=postgresql
|
204
|
+
```
|
data/Rakefile
CHANGED
@@ -1,20 +1,11 @@
|
|
1
|
-
require
|
2
|
-
|
3
|
-
require 'rake'
|
1
|
+
require 'bundler/gem_tasks'
|
4
2
|
require 'rake/testtask'
|
5
|
-
# require 'rake/rdoctask'
|
6
3
|
|
7
|
-
|
8
|
-
task :default => :test
|
4
|
+
task default: :test
|
9
5
|
|
10
|
-
desc '
|
6
|
+
desc 'Run tests'
|
11
7
|
Rake::TestTask.new(:test) do |t|
|
12
8
|
t.libs << 'test'
|
13
9
|
t.pattern = 'test/**/*_test.rb'
|
14
10
|
t.verbose = true
|
15
11
|
end
|
16
|
-
|
17
|
-
desc 'Copy migration file to db/migration of plugin'
|
18
|
-
file 'copy_migration' do
|
19
|
-
cp "generators/redmine_crm_migration/templates/migration.rb", "db/migrate/redmine_crm.rb"
|
20
|
-
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# This is a sample build configuration for Ruby.
|
2
|
+
# Check our guides at https://confluence.atlassian.com/x/8r-5Mw for more examples.
|
3
|
+
# Only use spaces to indent your .yml configuration.
|
4
|
+
# -----
|
5
|
+
# You can specify a custom docker image from Docker Hub as your build environment.
|
6
|
+
|
7
|
+
pipelines:
|
8
|
+
default:
|
9
|
+
- step:
|
10
|
+
name: New ruby
|
11
|
+
image: ruby:2.4.1
|
12
|
+
script:
|
13
|
+
- sed -i "s/'sqlite3'/'sqlite3', '~> 1.3.6'/g" redmine_crm.gemspec
|
14
|
+
- sed -i "s/'mysql2'/'mysql2', '~> 0.4.0'/g" redmine_crm.gemspec
|
15
|
+
- bundle install
|
16
|
+
- bundle exec rake test DB=sqlite
|
17
|
+
- bundle exec rake test DB=postgresql
|
18
|
+
- bundle exec rake test DB=mysql
|
19
|
+
services:
|
20
|
+
- mysql
|
21
|
+
- postgres
|
22
|
+
- step:
|
23
|
+
name: Old ruby
|
24
|
+
image: ruby:1.9.3
|
25
|
+
script:
|
26
|
+
- bundle install
|
27
|
+
- bundle exec rake test DB=mysql
|
28
|
+
services:
|
29
|
+
- mysql
|
30
|
+
|
31
|
+
definitions:
|
32
|
+
services:
|
33
|
+
mysql:
|
34
|
+
image: mysql:5.7
|
35
|
+
environment:
|
36
|
+
MYSQL_DATABASE: redmine_crm_test
|
37
|
+
MYSQL_ROOT_PASSWORD: password
|
38
|
+
postgres:
|
39
|
+
image: postgres
|
40
|
+
environment:
|
41
|
+
POSTGRES_DB: redmine_crm_test
|
42
|
+
POSTGRES_PASSWORD: password
|
data/config/currency_iso.json
CHANGED
@@ -2528,5 +2528,17 @@
|
|
2528
2528
|
"thousands_separator": ",",
|
2529
2529
|
"iso_numeric": "967",
|
2530
2530
|
"smallest_denomination": 5
|
2531
|
+
},
|
2532
|
+
"btc": {
|
2533
|
+
"priority": 100,
|
2534
|
+
"iso_code": "BTC",
|
2535
|
+
"name": "Bitcoin",
|
2536
|
+
"symbol": "฿",
|
2537
|
+
"subunit": "sat",
|
2538
|
+
"subunit_to_unit": 100000000,
|
2539
|
+
"symbol_first": false,
|
2540
|
+
"html_entity": "฿",
|
2541
|
+
"decimal_mark": ",",
|
2542
|
+
"thousands_separator": "."
|
2531
2543
|
}
|
2532
2544
|
}
|
data/doc/CHANGELOG
CHANGED
@@ -1,8 +1,87 @@
|
|
1
1
|
== Redmine CRM gem changelog
|
2
2
|
|
3
3
|
Redmine crm gem - general functions for plugins (tags, vote, viewing, currency)
|
4
|
-
Copyright (C) 2011-
|
5
|
-
|
4
|
+
Copyright (C) 2011-2019 RedmineUP
|
5
|
+
https://www.redmineup.com/
|
6
|
+
|
7
|
+
== 2019-05-07 v0.0.43
|
8
|
+
|
9
|
+
* custom_field and custom_fields methods added from Reporter plugin
|
10
|
+
* Added support for multi email contacts select
|
11
|
+
* Fixed Safari select2 bug with moving screen
|
12
|
+
* Fixed after_action method compatibility
|
13
|
+
|
14
|
+
== 2018-10-24 v0.0.42
|
15
|
+
|
16
|
+
* Hotfix for ruby 1.9.3 hashes support
|
17
|
+
* Added ci image for ruby 1.9.3
|
18
|
+
|
19
|
+
== 2018-10-23 v0.0.41
|
20
|
+
|
21
|
+
* New fields for IssueDrop: tags, checklists, story_points, color, day_in_state
|
22
|
+
* New Liquid filters for managing colors: darken_color, lighten_color, contrasting_text_color, hex_color, convert_to_brightness_value
|
23
|
+
* Fixes for Drops to use nil delegates
|
24
|
+
|
25
|
+
== 2018-09-28 v0.0.40
|
26
|
+
|
27
|
+
* acts_as_draftable adopted for Redmine projects
|
28
|
+
* New Liquid Drops: JournalsDrop, JournalDrop, TimeEntriesDrop, TimeEntryDrop
|
29
|
+
* New liquid properties for issues: done_ratio, estimated_hours, spent_hours, total_spent_hours, total_estimated_hours, is_private, closed_on, assignee, tracker, status, priority, category, version, time_entries, parent, project, subtasks, notes, journals
|
30
|
+
|
31
|
+
== 2018-03-28 v0.0.37
|
32
|
+
|
33
|
+
* Added rcrm_acts_as_draftable
|
34
|
+
* Added transform_to_select2 helper
|
35
|
+
|
36
|
+
== 2018-03-22 v0.0.36
|
37
|
+
|
38
|
+
* select2_tag improvements
|
39
|
+
|
40
|
+
== 2018-03-05 v0.0.35
|
41
|
+
|
42
|
+
* Added select2_tag helper
|
43
|
+
|
44
|
+
== 2017-12-22 v0.0.34
|
45
|
+
|
46
|
+
* Fixed bug with Redmine 2.x support
|
47
|
+
|
48
|
+
== 2017-12-18 v0.0.33
|
49
|
+
|
50
|
+
* Rails 5 support (Redmine 4)
|
51
|
+
* rcrm_acts_as_list (Redmine 4)
|
52
|
+
* Bitcoin currency support
|
53
|
+
|
54
|
+
== 2017-07-18 v0.0.32
|
55
|
+
|
56
|
+
* charjs added
|
57
|
+
|
58
|
+
== 2017-05-29 v0.0.31
|
59
|
+
|
60
|
+
* select2 controls for contacts and people
|
61
|
+
|
62
|
+
== 2017-05-23 v0.0.30
|
63
|
+
|
64
|
+
* Fixed votable vote_by
|
65
|
+
|
66
|
+
== 2017-03-21 v0.0.29
|
67
|
+
|
68
|
+
* Updated available_tags method
|
69
|
+
|
70
|
+
== 2017-03-17 v0.0.28
|
71
|
+
|
72
|
+
* Fixed bug with quote_value
|
73
|
+
|
74
|
+
== 2017-03-13 v0.0.27
|
75
|
+
|
76
|
+
* Added IP to Votes
|
77
|
+
|
78
|
+
== 2017-03-10 v0.0.26
|
79
|
+
|
80
|
+
* Liquid gem with base filters and drops for Redmine objects
|
81
|
+
|
82
|
+
== 2016-11-12 v0.0.24
|
83
|
+
|
84
|
+
* Liquid gem dependency
|
6
85
|
|
7
86
|
== 2016-09-28 v0.0.23
|
8
87
|
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# The MIT License (MIT)
|
2
|
+
|
3
|
+
# Copyright (c) 2016-2018 Georg Ledermann
|
4
|
+
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
10
|
+
# furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
# The above copyright notice and this permission notice shall be included in
|
13
|
+
# all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
# THE SOFTWARE.
|
22
|
+
|
23
|
+
module RedmineCrm
|
24
|
+
module ActsAsDraftable
|
25
|
+
class Draft < ActiveRecord::Base
|
26
|
+
belongs_to :user
|
27
|
+
belongs_to :parent, polymorphic: true
|
28
|
+
|
29
|
+
validates_presence_of :data, :target_type
|
30
|
+
|
31
|
+
def restore
|
32
|
+
target_type.constantize.from_draft(self)
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.restore_all
|
36
|
+
find_each.map(&:restore)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,170 @@
|
|
1
|
+
# The MIT License (MIT)
|
2
|
+
|
3
|
+
# Copyright (c) 2016-2018 Georg Ledermann
|
4
|
+
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
10
|
+
# furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
# The above copyright notice and this permission notice shall be included in
|
13
|
+
# all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
# THE SOFTWARE.
|
22
|
+
|
23
|
+
module RedmineCrm
|
24
|
+
module ActsAsDraftable #:nodoc: all
|
25
|
+
module Base
|
26
|
+
ALLOWED_DRAFT_OPTIONS = [:parent]
|
27
|
+
|
28
|
+
def draftable?
|
29
|
+
false
|
30
|
+
end
|
31
|
+
|
32
|
+
def rcrm_acts_as_draftable(options = {})
|
33
|
+
raise ArgumentError unless options.is_a?(Hash)
|
34
|
+
raise ArgumentError unless options.keys.all? { |k| ALLOWED_DRAFT_OPTIONS.include?(k) }
|
35
|
+
|
36
|
+
class_attribute :draft_parent
|
37
|
+
|
38
|
+
if options[:parent]
|
39
|
+
parent_class = self.reflect_on_all_associations(:belongs_to).find { |a| a.name == options[:parent] }.try(:klass)
|
40
|
+
raise ArgumentError unless parent_class
|
41
|
+
|
42
|
+
unless parent_class.method_defined?(:drafts)
|
43
|
+
parent_class.class_eval do
|
44
|
+
def drafts(user)
|
45
|
+
Draft.where(user: user, parent: self)
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.child_drafts(user)
|
49
|
+
Draft.where(user: user, parent_type: self.base_class.name)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
self.draft_parent = options[:parent]
|
55
|
+
end
|
56
|
+
|
57
|
+
attr_accessor :draft_id
|
58
|
+
before_save :clear_draft
|
59
|
+
|
60
|
+
extend RedmineCrm::ActsAsDraftable::ClassMethods
|
61
|
+
include RedmineCrm::ActsAsDraftable::InstanceMethods
|
62
|
+
end
|
63
|
+
end # Base
|
64
|
+
|
65
|
+
module ClassMethods
|
66
|
+
def draftable?
|
67
|
+
true
|
68
|
+
end
|
69
|
+
|
70
|
+
def from_draft(draft_or_id)
|
71
|
+
draft = draft_or_id.is_a?(Draft) ? draft_or_id : Draft.find(draft_or_id)
|
72
|
+
raise ArgumentError unless draft.target_type == name
|
73
|
+
|
74
|
+
target = draft.target_type.constantize.new
|
75
|
+
target.load_from_draft(draft.data)
|
76
|
+
|
77
|
+
target.draft_id = draft.id
|
78
|
+
target
|
79
|
+
end
|
80
|
+
|
81
|
+
def drafts(user)
|
82
|
+
Draft.where(user_id: user.id, target_type: name)
|
83
|
+
end
|
84
|
+
end # ClassMethods
|
85
|
+
|
86
|
+
module InstanceMethods
|
87
|
+
def save_draft
|
88
|
+
return false unless new_record? || changed?
|
89
|
+
|
90
|
+
draft = self.draft || Draft.new
|
91
|
+
draft.data = dump_to_draft
|
92
|
+
draft.user_id = User.current.try(:id)
|
93
|
+
draft.parent = parent_for_draft
|
94
|
+
draft.target_type = self.class.name
|
95
|
+
|
96
|
+
result = draft.save
|
97
|
+
self.draft_id = draft.id if result
|
98
|
+
result
|
99
|
+
end
|
100
|
+
|
101
|
+
def update_draft(attributes)
|
102
|
+
with_transaction_returning_status do
|
103
|
+
assign_attributes(attributes)
|
104
|
+
save_draft
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def draft
|
109
|
+
Draft.find_by_id(draft_id)
|
110
|
+
end
|
111
|
+
|
112
|
+
def parent_for_draft
|
113
|
+
return self if id.present?
|
114
|
+
|
115
|
+
self.class.draft_parent.present? ? send(self.class.draft_parent) : self
|
116
|
+
end
|
117
|
+
|
118
|
+
def last_draft
|
119
|
+
@last_draft ||= RedmineCrm::ActsAsDraftable::Draft.where(
|
120
|
+
target_type: self.class.name,
|
121
|
+
parent_type: parent_for_draft.try(:class).try(:to_s),
|
122
|
+
parent_id: parent_for_draft.try(:id),
|
123
|
+
user_id: User.current.try(:id)
|
124
|
+
).last
|
125
|
+
end
|
126
|
+
|
127
|
+
def dump_to_draft
|
128
|
+
instance_values.default = nil
|
129
|
+
Marshal.dump(instance_values)
|
130
|
+
end
|
131
|
+
|
132
|
+
def load_from_draft(string)
|
133
|
+
values = Marshal.load(string)
|
134
|
+
|
135
|
+
values.each do |name, value|
|
136
|
+
instance_variable_set("@#{name}", value)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
def clear_draft
|
141
|
+
if last_draft && last_draft.destroy
|
142
|
+
self.draft_id = nil
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end # InstanceMethods
|
146
|
+
|
147
|
+
module Migration
|
148
|
+
def create_drafts_table
|
149
|
+
return if connection.table_exists?(:drafts)
|
150
|
+
|
151
|
+
connection.create_table :drafts do |t|
|
152
|
+
t.string :target_type, limit: 150, null: false
|
153
|
+
t.references :user
|
154
|
+
t.references :parent, polymorphic: true
|
155
|
+
t.binary :data, limit: 16777215, null: false
|
156
|
+
t.datetime :updated_at, null: false
|
157
|
+
end
|
158
|
+
|
159
|
+
connection.add_index :drafts, [:user_id, :target_type]
|
160
|
+
end
|
161
|
+
|
162
|
+
def drop_drafts_table
|
163
|
+
connection.drop_table :drafts if connection.table_exists?(:drafts)
|
164
|
+
end
|
165
|
+
end # Migration
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
ActiveRecord::Base.extend RedmineCrm::ActsAsDraftable::Base
|
170
|
+
ActiveRecord::Base.extend RedmineCrm::ActsAsDraftable::Migration
|