redmine_crm 0.0.43 → 0.0.63

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.
Files changed (65) hide show
  1. checksums.yaml +5 -5
  2. data/Gemfile +1 -1
  3. data/app/controllers/redmine_crm_controller.rb +26 -0
  4. data/app/views/redmine_crm/_money.html.erb +44 -0
  5. data/app/views/redmine_crm/settings.html.erb +10 -0
  6. data/bitbucket-pipelines.yml +1 -8
  7. data/config/currency_iso.json +1 -1
  8. data/config/locales/cs.yml +13 -0
  9. data/config/locales/de.yml +13 -0
  10. data/config/locales/en.yml +13 -0
  11. data/config/locales/es.yml +13 -0
  12. data/config/locales/ru.yml +13 -0
  13. data/config/routes.rb +5 -0
  14. data/doc/CHANGELOG +92 -1
  15. data/lib/redmine_crm/acts_as_draftable/draft.rb +1 -1
  16. data/lib/redmine_crm/acts_as_draftable/rcrm_acts_as_draftable.rb +4 -2
  17. data/lib/redmine_crm/acts_as_priceable/rcrm_acts_as_priceable.rb +33 -0
  18. data/lib/redmine_crm/acts_as_taggable/rcrm_acts_as_taggable.rb +10 -3
  19. data/lib/redmine_crm/acts_as_taggable/tag_list.rb +1 -1
  20. data/lib/redmine_crm/acts_as_viewed/rcrm_acts_as_viewed.rb +1 -1
  21. data/lib/redmine_crm/acts_as_votable/rcrm_acts_as_votable.rb +1 -1
  22. data/lib/redmine_crm/acts_as_votable/votable.rb +2 -2
  23. data/lib/redmine_crm/compatibility/routing_mapper_patch.rb +27 -0
  24. data/lib/redmine_crm/currency/formatting.rb +5 -5
  25. data/lib/redmine_crm/currency.rb +28 -17
  26. data/lib/redmine_crm/engine.rb +4 -0
  27. data/lib/redmine_crm/helpers/calendars_helper.rb +22 -0
  28. data/lib/redmine_crm/helpers/external_assets_helper.rb +1 -0
  29. data/lib/redmine_crm/helpers/form_tag_helper.rb +12 -0
  30. data/lib/redmine_crm/hooks/views_layouts_hook.rb +12 -0
  31. data/lib/redmine_crm/liquid/drops/attachment_drop.rb +47 -0
  32. data/lib/redmine_crm/liquid/drops/issue_relations_drop.rb +41 -0
  33. data/lib/redmine_crm/liquid/drops/issues_drop.rb +54 -28
  34. data/lib/redmine_crm/liquid/drops/time_entries_drop.rb +1 -1
  35. data/lib/redmine_crm/liquid/filters/arrays.rb +1 -1
  36. data/lib/redmine_crm/liquid/filters/base.rb +36 -4
  37. data/lib/redmine_crm/money_helper.rb +15 -14
  38. data/lib/redmine_crm/patches/liquid_patch.rb +33 -0
  39. data/lib/redmine_crm/settings/money.rb +46 -0
  40. data/lib/redmine_crm/settings.rb +53 -0
  41. data/lib/redmine_crm/version.rb +1 -1
  42. data/lib/redmine_crm.rb +15 -2
  43. data/redmine_crm.gemspec +4 -2
  44. data/test/acts_as_draftable/rcrm_acts_as_draftable_test.rb +0 -1
  45. data/test/acts_as_taggable/rcrm_acts_as_taggable_test.rb +97 -92
  46. data/test/fixtures/attachments.yml +14 -0
  47. data/test/liquid/drops/attachment_drop_test.rb +15 -0
  48. data/test/liquid/drops/issue_relations_drop_test.rb +24 -0
  49. data/test/liquid/drops/issues_drop_test.rb +4 -0
  50. data/test/liquid/filters/base_filter_test.rb +5 -1
  51. data/test/models/attachment.rb +3 -0
  52. data/test/models/issue.rb +7 -0
  53. data/test/models/issue_relation.rb +10 -0
  54. data/test/money_helper_test.rb +1 -1
  55. data/test/schema.rb +22 -1
  56. data/test/tags_helper_test.rb +4 -4
  57. data/vendor/assets/images/money.png +0 -0
  58. data/vendor/assets/javascripts/select2.js +2 -3
  59. data/vendor/assets/javascripts/select2_helpers.js +8 -2
  60. data/vendor/assets/javascripts/timepicker_addon.js +5 -0
  61. data/vendor/assets/stylesheets/calendars.css +15 -0
  62. data/vendor/assets/stylesheets/money.css +3 -0
  63. data/vendor/assets/stylesheets/select2.css +28 -18
  64. data/vendor/assets/stylesheets/timepicker_addon.css +5 -0
  65. metadata +57 -10
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RedmineCrm
4
+ module Hooks
5
+ class ViewsLayoutsHook < Redmine::Hook::ViewListener
6
+ def view_layouts_base_html_head(_context = {})
7
+ stylesheet_link_tag(:calendars, plugin: 'redmine_crm') +
8
+ stylesheet_link_tag(:money, plugin: 'redmine_crm')
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,47 @@
1
+ module RedmineCrm
2
+ module Liquid
3
+ class AttachmentDrop < ::Liquid::Drop
4
+ delegate :id,
5
+ :filename,
6
+ :title,
7
+ :description,
8
+ :filesize,
9
+ :content_type,
10
+ :digest,
11
+ :downloads,
12
+ :created_on,
13
+ :token,
14
+ :visible?,
15
+ :image?,
16
+ :thumbnailable?,
17
+ :is_text?,
18
+ :readable?,
19
+ to: :@attachment
20
+
21
+ def initialize(attachment)
22
+ @attachment = attachment
23
+ end
24
+
25
+ def url(options = {})
26
+ Rails.application.routes.url_helpers.download_named_attachment_url(@attachment, { filename: filename,
27
+ host: Setting.host_name,
28
+ protocol: Setting.protocol }.merge(options))
29
+ end
30
+
31
+ def link
32
+ link_to((@attachment.description.blank? ? @attachment.filename : @attachment.description), url)
33
+ end
34
+
35
+ def author
36
+ @author ||= UserDrop.new @attachment.author
37
+ end
38
+
39
+ def read
40
+ @content ||= if @attachment.is_text? && @attachment.filesize <= Setting.file_max_size_displayed.to_i.kilobyte
41
+ File.new(@attachment.diskfile, "rb").read
42
+ end
43
+ @content
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,41 @@
1
+ module RedmineCrm
2
+ module Liquid
3
+ class IssueRelationsDrop < ::Liquid::Drop
4
+ def initialize(relations)
5
+ @relations = relations
6
+ end
7
+
8
+ def all
9
+ @all ||= @relations.map { |relation| IssueRelationDrop.new(relation) }
10
+ end
11
+
12
+ def visible
13
+ @visible ||= @all.select(&:visible?)
14
+ end
15
+
16
+ def each(&block)
17
+ all.each(&block)
18
+ end
19
+
20
+ def size
21
+ @relations.size
22
+ end
23
+ end
24
+
25
+ class IssueRelationDrop < ::Liquid::Drop
26
+ delegate :relation_type, :delay, to: :@relation
27
+
28
+ def initialize(relation)
29
+ @relation = relation
30
+ end
31
+
32
+ def issue_from
33
+ @issue_from ||= IssueDrop.new(@relation.issue_from)
34
+ end
35
+
36
+ def issue_to
37
+ @issue_to ||= IssueDrop.new(@relation.issue_to)
38
+ end
39
+ end
40
+ end
41
+ end
@@ -6,14 +6,15 @@ module RedmineCrm
6
6
  end
7
7
 
8
8
  def before_method(id)
9
- issue = @issues.where(:id => id).first || Issue.new
9
+ issue = @issues.where(id: id).first || Issue.new
10
10
  IssueDrop.new issue
11
11
  end
12
12
 
13
13
  def all
14
- @all ||= @issues.map do |issue|
15
- IssueDrop.new issue
16
- end
14
+ @all ||=
15
+ @issues.map do |issue|
16
+ IssueDrop.new issue
17
+ end
17
18
  end
18
19
 
19
20
  def visible
@@ -34,9 +35,8 @@ module RedmineCrm
34
35
 
35
36
  delegate :id,
36
37
  :subject,
37
- :description,
38
38
  :visible?,
39
- :open?,
39
+ :closed?,
40
40
  :start_date,
41
41
  :due_date,
42
42
  :overdue?,
@@ -49,14 +49,14 @@ module RedmineCrm
49
49
  :closed_on,
50
50
  :updated_on,
51
51
  :created_on,
52
- :to => :@issue
52
+ to: :@issue
53
53
 
54
54
  def initialize(issue)
55
55
  @issue = issue
56
56
  end
57
57
 
58
58
  def link
59
- link_to @issue.subject, self.url
59
+ link_to @issue.subject, url
60
60
  end
61
61
 
62
62
  def url
@@ -96,23 +96,35 @@ module RedmineCrm
96
96
  end
97
97
 
98
98
  def parent
99
- @parent ||= IssueDrop.new @issue.parent if @issue.parent
99
+ @parent ||= IssueDrop.new @issue.parent if @issue.parent
100
100
  end
101
101
 
102
102
  def project
103
- @project ||= ProjectDrop.new @issue.project if @issue.project
103
+ @project ||= ProjectDrop.new @issue.project if @issue.project
104
+ end
105
+
106
+ def description
107
+ @description ||= replace_images_urls(@issue.description)
104
108
  end
105
109
 
106
110
  def subtasks
107
- @subtasks ||= IssuesDrop.new @issue.children
111
+ @subtasks ||= IssuesDrop.new @issue.children
112
+ end
113
+
114
+ def relations_from
115
+ @relations_from ||= IssueRelationsDrop.new(@issue.relations_from.select { |r| r.other_issue(@issue) && r.other_issue(@issue).visible? })
116
+ end
117
+
118
+ def relations_to
119
+ @relations_to ||= IssueRelationsDrop.new(@issue.relations_to.select { |r| r.other_issue(@issue) && r.other_issue(@issue).visible? })
108
120
  end
109
121
 
110
122
  def notes
111
- @notes ||= @issue.journals.where("#{Journal.table_name}.notes IS NOT ?", nil).order(:created_on).map(&:notes)
123
+ @notes ||= @issue.journals.where.not(notes: [nil, '']).order(:created_on).map(&:notes).map { |note| replace_images_urls(note) }
112
124
  end
113
125
 
114
126
  def journals
115
- @journals ||= JournalsDrop.new @issue.journals.where("#{Journal.table_name}.notes IS NOT ?", nil)
127
+ @journals ||= JournalsDrop.new(@issue.journals.where.not(notes: nil).find_each { |journal| journal.notes = replace_images_urls(journal.notes) })
116
128
  end
117
129
 
118
130
  def tags
@@ -126,19 +138,39 @@ module RedmineCrm
126
138
  def color
127
139
  @issue.respond_to?(:color) && @issue.color
128
140
  end
129
-
141
+
130
142
  def day_in_state
131
143
  @issue.respond_to?(:day_in_state) && @issue.day_in_state
132
144
  end
133
145
 
134
146
  def checklists
135
- @issue.respond_to?(:checklists) && @issue.checklists.map{|item| {"id_done" => item.is_done, "subject" => item.subject}}
147
+ @issue.respond_to?(:checklists) && @issue.checklists.map do |item|
148
+ { 'id_done' => item.is_done, 'subject' => item.subject, 'is_section' => item.is_section }
149
+ end
150
+ end
151
+
152
+ def helpdesk_ticket
153
+ return nil unless defined?(::HelpdeskTicketDrop)
154
+
155
+ @helpdesk_ticket ||= HelpdeskTicketDrop.new(@issue)
136
156
  end
137
157
 
138
158
  def custom_field_values
139
159
  @issue.custom_field_values
140
- end
160
+ end
161
+
162
+ private
141
163
 
164
+ def replace_images_urls(text)
165
+ text.gsub(/\!.*\!/) do |i_name|
166
+ i_name = i_name.delete('!')
167
+ i_name_css = i_name.scan(/^\{.*\}/).first.to_s
168
+ attachment = @issue.attachments.find_by(filename: i_name.gsub(i_name_css, ''))
169
+ image = AttachmentDrop.new attachment if attachment
170
+ attach_url = image.try(:url)
171
+ attach_url ? "!#{i_name_css}#{attach_url}!" : i_name
172
+ end
173
+ end
142
174
  end
143
175
 
144
176
  class JournalsDrop < ::Liquid::Drop
@@ -147,9 +179,10 @@ module RedmineCrm
147
179
  end
148
180
 
149
181
  def all
150
- @all ||= @journals.map do |journal|
151
- JournalDrop.new journal
152
- end
182
+ @all ||=
183
+ @journals.map do |journal|
184
+ JournalDrop.new journal
185
+ end
153
186
  end
154
187
 
155
188
  def visible
@@ -166,12 +199,7 @@ module RedmineCrm
166
199
  end
167
200
 
168
201
  class JournalDrop < ::Liquid::Drop
169
- delegate :id,
170
- :notes,
171
- :created_on,
172
- :private_notes,
173
- :to => :@journal,
174
- allow_nil: true
202
+ delegate :id, :notes, :created_on, :private_notes, to: :@journal, allow_nil: true
175
203
 
176
204
  def initialize(journal)
177
205
  @journal = journal
@@ -182,10 +210,8 @@ module RedmineCrm
182
210
  end
183
211
 
184
212
  def issue
185
- @issue ||= IssueDrop.new @journal.issue if @journal.issue
213
+ @issue ||= IssueDrop.new @journal.issue if @journal.issue
186
214
  end
187
-
188
215
  end
189
-
190
216
  end
191
217
  end
@@ -49,7 +49,7 @@ module RedmineCrm
49
49
  end
50
50
 
51
51
  def issue
52
- @issue ||= IssueDrop.new(@time_entry.issue)
52
+ @issue ||= IssueDrop.new(@time_entry.issue) unless @time_entry.issue.blank?
53
53
  end
54
54
 
55
55
  def activity
@@ -100,7 +100,7 @@ module RedmineCrm
100
100
  def tagged_with(input, tags, match='all')
101
101
  return input unless input.respond_to?(:select)
102
102
  input = input.values if input.is_a?(Hash)
103
- tag_list = input.is_a?(Array) ? tags.sort : tags.split(',').map(&:strip).sort
103
+ tag_list = tags.is_a?(Array) ? tags.sort : tags.split(',').map(&:strip).sort
104
104
  case match
105
105
  when "all"
106
106
  input.select do |object|
@@ -36,7 +36,7 @@ module RedmineCrm
36
36
 
37
37
  def md5(input)
38
38
  Digest::MD5.hexdigest(input) unless input.blank?
39
- end
39
+ end
40
40
 
41
41
  # example:
42
42
  # {{ "http:://www.example.com?key=hello world" | encode }}
@@ -87,8 +87,8 @@ module RedmineCrm
87
87
  to_number(input).floor.to_i
88
88
  end
89
89
 
90
- def currency(input, currency_code = 'USD')
91
- price_to_currency(input, currency_code, :converted => false)
90
+ def currency(input, currency_code = nil)
91
+ price_to_currency(input, currency_code || container_currency, :converted => false)
92
92
  end
93
93
 
94
94
  def call_method(input, method_name)
@@ -100,7 +100,7 @@ module RedmineCrm
100
100
  def custom_field(input, field_name)
101
101
  if input.respond_to?(:custom_field_values)
102
102
  custom_value = input.custom_field_values.detect { |cfv| cfv.custom_field.name == field_name }
103
- custom_value.custom_field.format.formatted_custom_value(nil, custom_value)
103
+ custom_value.custom_field.format.formatted_custom_value(nil, custom_value) if custom_value
104
104
  end
105
105
  end
106
106
 
@@ -121,6 +121,30 @@ module RedmineCrm
121
121
  end
122
122
  end
123
123
 
124
+ def multi_line(input)
125
+ input.to_s.gsub("\n", '<br/>').html_safe
126
+ end
127
+
128
+ def concat(input, *args)
129
+ result = input.to_s
130
+ args.flatten.each { |a| result << a.to_s }
131
+ result
132
+ end
133
+
134
+ # right justify and padd a string
135
+ def rjust(input, integer, padstr = '')
136
+ input.to_s.rjust(integer, padstr)
137
+ end
138
+
139
+ # left justify and padd a string
140
+ def ljust(input, integer, padstr = '')
141
+ input.to_s.ljust(integer, padstr)
142
+ end
143
+
144
+ def textile(input)
145
+ ::RedCloth3.new(input).to_html
146
+ end
147
+
124
148
  protected
125
149
 
126
150
  # Convert an array of properties ('key:value') into a hash
@@ -210,6 +234,14 @@ module RedmineCrm
210
234
  end
211
235
  end
212
236
  end
237
+
238
+ def container
239
+ @container ||= @context.registers[:container]
240
+ end
241
+
242
+ def container_currency
243
+ container.currency if container.respond_to?(:currency)
244
+ end
213
245
  end
214
246
  ::Liquid::Template.register_filter(RedmineCrm::Liquid::Filters::Base)
215
247
  end
@@ -1,14 +1,14 @@
1
1
  require 'action_view'
2
+ require 'redmine_crm/settings/money'
2
3
 
3
4
  module RedmineCrm
4
5
  module MoneyHelper
5
-
6
6
  def object_price(obj, price_field = :price, options = {})
7
7
  options.merge!({:symbol => true})
8
8
  price_to_currency(obj.try(price_field), obj.currency, options).to_s if obj.respond_to?(:currency)
9
9
  end
10
10
 
11
- def prices_collection_by_currency(prices_collection, options={})
11
+ def prices_collection_by_currency(prices_collection, options = {})
12
12
  return [] if prices_collection.blank? || prices_collection == 0
13
13
  prices = prices_collection
14
14
  prices.reject!{|k, v| v.to_i == 0} if options[:hide_zeros]
@@ -18,17 +18,17 @@ module RedmineCrm
18
18
  def deal_currency_icon(currency)
19
19
  case currency.to_s.upcase
20
20
  when 'EUR'
21
- "icon-money-euro"
21
+ 'icon-money-euro'
22
22
  when 'GBP'
23
- "icon-money-pound"
23
+ 'icon-money-pound'
24
24
  when 'JPY'
25
- "icon-money-yen"
25
+ 'icon-money-yen'
26
26
  else
27
- "icon-money-dollar"
27
+ 'icon-money-dollar'
28
28
  end
29
29
  end
30
30
 
31
- def collection_for_currencies_select(default_currency = 'USD', major_currencies = %w(USD EUR GBP RUB CHF))
31
+ def collection_for_currencies_select(default_currency = RedmineCrm::Settings::Money.default_currency, major_currencies = RedmineCrm::Settings::Money.major_currencies)
32
32
  currencies = []
33
33
  currencies << default_currency.to_s unless default_currency.blank?
34
34
  currencies |= major_currencies
@@ -46,17 +46,18 @@ module RedmineCrm
46
46
  end.sort{|x, y| x[0] <=> y[0]}
47
47
  end
48
48
 
49
- def price_to_currency(price, currency="USD", options={})
49
+ def price_to_currency(price, currency = RedmineCrm::Settings::Money.default_currency, options = {})
50
50
  return '' if price.blank?
51
51
 
52
- currency = "USD" unless currency.is_a?(String)
53
- currency = RedmineCrm::Currency.find(currency)
52
+ currency = 'USD' unless currency.is_a?(String)
53
+ default_options = {
54
+ decimal_mark: RedmineCrm::Settings::Money.decimal_separator,
55
+ thousands_separator: RedmineCrm::Settings::Money.thousands_delimiter
56
+ }.reject { |_k, v| v.nil? }
54
57
 
55
- return RedmineCrm::Currency.format(price.to_f, currency, options)# if currency
56
- price.to_s
58
+ currency = RedmineCrm::Currency.find(currency)
59
+ RedmineCrm::Currency.format(price.to_f, currency, default_options.merge(options))
57
60
  end
58
-
59
-
60
61
  end
61
62
  end
62
63
 
@@ -0,0 +1,33 @@
1
+ module RedmineCrm
2
+ module Patches
3
+ module LiquidPatch
4
+ module StandardFilters
5
+
6
+ def self.included(base)
7
+ base.class_eval do
8
+
9
+ private
10
+
11
+ def to_number(obj)
12
+ case obj
13
+ when Float
14
+ BigDecimal(obj.to_s)
15
+ when Numeric
16
+ obj
17
+ when String
18
+ (obj.strip =~ /^\d+\.\d+$/) ? BigDecimal(obj) : obj.to_i
19
+ else
20
+ 0
21
+ end
22
+ end
23
+ end
24
+ end
25
+
26
+ end
27
+ end
28
+ end
29
+ end
30
+
31
+ unless Liquid::StandardFilters.included_modules.include?(RedmineCrm::Patches::LiquidPatch::StandardFilters)
32
+ Liquid::StandardFilters.send(:include, RedmineCrm::Patches::LiquidPatch::StandardFilters)
33
+ end
@@ -0,0 +1,46 @@
1
+ require 'redmine_crm/settings'
2
+
3
+ module RedmineCrm
4
+ class Settings
5
+ class Money
6
+ TAX_TYPE_EXCLUSIVE = 1
7
+ TAX_TYPE_INCLUSIVE = 2
8
+
9
+ class << self
10
+ def default_currency
11
+ RedmineCrm::Settings['default_currency'] || 'USD'
12
+ end
13
+
14
+ def major_currencies
15
+ currencies = RedmineCrm::Settings['major_currencies'].to_s.split(',').select { |c| !c.blank? }.map(&:strip)
16
+ currencies = %w[USD EUR GBP RUB CHF] if currencies.blank?
17
+ currencies.compact.uniq
18
+ end
19
+
20
+ def default_tax
21
+ RedmineCrm::Settings['default_tax'].to_f
22
+ end
23
+
24
+ def tax_type
25
+ ((['1', '2'] & [RedmineCrm::Settings['tax_type'].to_s]).first || TAX_TYPE_EXCLUSIVE).to_i
26
+ end
27
+
28
+ def tax_exclusive?
29
+ tax_type == TAX_TYPE_EXCLUSIVE
30
+ end
31
+
32
+ def thousands_delimiter
33
+ ([' ', ',', '.'] & [RedmineCrm::Settings['thousands_delimiter']]).first
34
+ end
35
+
36
+ def decimal_separator
37
+ ([',', '.'] & [RedmineCrm::Settings['decimal_separator']]).first
38
+ end
39
+
40
+ def disable_taxes?
41
+ RedmineCrm::Settings['disable_taxes'].to_i > 0
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,53 @@
1
+ module RedmineCrm
2
+ class Settings
3
+ SECTIONS = {
4
+ 'money' => { id: :money, label: :label_redmine_crm_money, partial: 'money' }
5
+ }.freeze
6
+
7
+ class << self
8
+ def initialize_gem_settings
9
+ return if !Object.const_defined?('Setting') || Setting.respond_to?(:plugin_redmine_crm)
10
+
11
+ if Setting.respond_to?(:define_setting)
12
+ Setting.send(:define_setting, 'plugin_redmine_crm', 'default' => default_settings, 'serialized' => true)
13
+ elsif Setting.respond_to?(:available_settings)
14
+ Setting.available_settings['plugin_redmine_crm'] = { 'default' => default_settings, 'serialized' => true }
15
+ Setting.class.send(:define_method, 'plugin_redmine_crm', -> { Setting['plugin_redmine_crm'] })
16
+ Setting.class.send(:define_method, 'plugin_redmine_crm=', lambda do |val|
17
+ setting = find_or_default('plugin_redmine_crm')
18
+ setting.value = val || ''
19
+ @cached_settings['plugin_redmine_crm'] = nil
20
+ setting.save(validate: false)
21
+ setting.value
22
+ end)
23
+ end
24
+ @settings_initialized
25
+ end
26
+
27
+ # Use apply instead attrs assign because it can rewrite other attributes
28
+ def apply=(values)
29
+ initialize_gem_settings unless @settings_initialized
30
+
31
+ Setting.plugin_redmine_crm = Setting.plugin_redmine_crm.merge(values)
32
+ end
33
+
34
+ def values
35
+ initialize_gem_settings unless @settings_initialized
36
+ Object.const_defined?('Setting') ? Setting.plugin_redmine_crm : {}
37
+ end
38
+
39
+ def [](value)
40
+ initialize_gem_settings unless @settings_initialized
41
+ return Setting.plugin_redmine_crm[value] if Object.const_defined?('Setting')
42
+
43
+ nil
44
+ end
45
+
46
+ private
47
+
48
+ def default_settings
49
+ {}
50
+ end
51
+ end
52
+ end
53
+ end
@@ -1,3 +1,3 @@
1
1
  module RedmineCrm
2
- VERSION = '0.0.43'
2
+ VERSION = '0.0.63'
3
3
  end
data/lib/redmine_crm.rb CHANGED
@@ -2,6 +2,10 @@ require 'active_record'
2
2
  require 'action_view'
3
3
 
4
4
  require 'redmine_crm/version'
5
+ require 'redmine_crm/engine'
6
+
7
+ require 'redmine_crm/settings'
8
+ require 'redmine_crm/settings/money'
5
9
 
6
10
  require 'redmine_crm/acts_as_list/list'
7
11
  require 'redmine_crm/acts_as_taggable/tag'
@@ -15,6 +19,7 @@ require 'redmine_crm/acts_as_votable/vote'
15
19
  require 'redmine_crm/acts_as_votable/voter'
16
20
  require 'redmine_crm/acts_as_draftable/rcrm_acts_as_draftable'
17
21
  require 'redmine_crm/acts_as_draftable/draft'
22
+ require 'redmine_crm/acts_as_priceable/rcrm_acts_as_priceable'
18
23
 
19
24
  require 'redmine_crm/currency'
20
25
  require 'redmine_crm/helpers/tags_helper'
@@ -30,12 +35,17 @@ require 'redmine_crm/liquid/drops/news_drop'
30
35
  require 'redmine_crm/liquid/drops/projects_drop'
31
36
  require 'redmine_crm/liquid/drops/users_drop'
32
37
  require 'redmine_crm/liquid/drops/time_entries_drop'
38
+ require 'redmine_crm/liquid/drops/attachment_drop'
39
+ require 'redmine_crm/liquid/drops/issue_relations_drop'
33
40
 
41
+ require 'redmine_crm/helpers/calendars_helper'
34
42
  require 'redmine_crm/helpers/external_assets_helper'
35
43
  require 'redmine_crm/helpers/form_tag_helper'
36
44
  require 'redmine_crm/assets_manager'
37
45
 
38
46
  require 'redmine_crm/compatibility/application_controller_patch'
47
+ require 'redmine_crm/compatibility/routing_mapper_patch'
48
+ require 'redmine_crm/patches/liquid_patch' unless BigDecimal.respond_to?(:new)
39
49
 
40
50
  module RedmineCrm
41
51
  GEM_NAME = 'redmine_crm'.freeze
@@ -50,6 +60,7 @@ end
50
60
  RedmineCrm::AssetsManager.install_assets
51
61
 
52
62
  if defined?(ActionView::Base)
63
+ ActionView::Base.send :include, RedmineCrm::CalendarsHelper
53
64
  ActionView::Base.send :include, RedmineCrm::ExternalAssetsHelper
54
65
  ActionView::Base.send :include, RedmineCrm::FormTagHelper
55
66
  end
@@ -57,6 +68,7 @@ end
57
68
  def requires_redmine_crm(arg)
58
69
  def compare_versions(requirement, current)
59
70
  raise ArgumentError.new('wrong version format') unless check_version_format(requirement)
71
+
60
72
  requirement = requirement.split('.').collect(&:to_i)
61
73
  requirement <=> current.slice(0, requirement.size)
62
74
  end
@@ -65,7 +77,7 @@ def requires_redmine_crm(arg)
65
77
  version =~ /^\d+.?\d*.?\d*$/m
66
78
  end
67
79
 
68
- arg = { :version_or_higher => arg } unless arg.is_a?(Hash)
80
+ arg = { version_or_higher: arg } unless arg.is_a?(Hash)
69
81
  arg.assert_valid_keys(:version, :version_or_higher)
70
82
 
71
83
  current = RedmineCrm::VERSION.split('.').map { |x| x.to_i }
@@ -73,6 +85,7 @@ def requires_redmine_crm(arg)
73
85
  case k
74
86
  when :version_or_higher
75
87
  raise ArgumentError.new(':version_or_higher accepts a version string only') unless req.is_a?(String)
88
+
76
89
  unless compare_versions(req, current) <= 0
77
90
  Rails.logger.error "\033[31m[ERROR]\033[0m Redmine requires redmine_crm gem version #{req} or higher (you're using #{RedmineCrm::VERSION}).\n\033[31m[ERROR]\033[0m Please update with 'bundle update redmine_crm'." if Rails.logger
78
91
  abort "\033[31mRedmine requires redmine_crm gem version #{req} or higher (you're using #{RedmineCrm::VERSION}).\nPlease update with 'bundle update redmine_crm'.\033[0m"
@@ -80,7 +93,7 @@ def requires_redmine_crm(arg)
80
93
  when :version
81
94
  req = [req] if req.is_a?(String)
82
95
  if req.is_a?(Array)
83
- unless req.detect {|ver| compare_versions(ver, current) == 0}
96
+ unless req.detect { |ver| compare_versions(ver, current) == 0 }
84
97
  abort "\033[31mRedmine requires redmine_crm gem version #{req} (you're using #{RedmineCrm::VERSION}).\nPlease update with 'bundle update redmine_crm'.\033[0m"
85
98
  end
86
99
  elsif req.is_a?(Range)
data/redmine_crm.gemspec CHANGED
@@ -10,16 +10,18 @@ Gem::Specification.new do |spec|
10
10
  spec.email = ["support@redminecrm.com"]
11
11
  spec.summary = %q{Common libraries for RedmineUP plugins for Redmine}
12
12
  spec.description = %q{Common libraries for RedmineUP plugins (www.redmineup.com) for Redmine. Requered Redmine from http://redmine.org}
13
- spec.homepage = ""
14
- spec.license = "GPL2"
13
+ spec.homepage = "https://www.redmineup.com"
14
+ spec.license = "GPL-2.0"
15
15
 
16
16
  spec.files = `git ls-files -z`.split("\x0")
17
17
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ["lib"]
20
+ spec.required_ruby_version = ">= 2.0.0"
20
21
 
21
22
  spec.add_runtime_dependency 'rails'
22
23
  spec.add_runtime_dependency 'liquid', '< 2.6.4'
24
+ spec.add_runtime_dependency 'rubyzip'
23
25
 
24
26
  spec.add_development_dependency 'sqlite3'
25
27
  spec.add_development_dependency 'mysql2'
@@ -7,7 +7,6 @@ class RcrmActsAsDraftableTest < ActiveSupport::TestCase
7
7
  end
8
8
  end
9
9
 
10
- class SomeClass < ActiveRecord::Base; end
11
10
  def test_rcrm_acts_as_draftable_with_parent
12
11
  assert_nothing_raised do
13
12
  News.rcrm_acts_as_draftable(parent: :author)