fat_free_crm 0.15.0.beta → 0.15.0.beta.2
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.
Potentially problematic release.
This version of fat_free_crm might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.rubocop.yml +7 -0
- data/.rubocop_todo.yml +517 -0
- data/.travis.yml +1 -1
- data/CHANGELOG.md +145 -9
- data/Gemfile +11 -13
- data/Gemfile.lock +104 -92
- data/README.md +2 -9
- data/app/assets/javascripts/application.js.erb +1 -1
- data/app/assets/javascripts/crm_select2.js.coffee +0 -1
- data/app/controllers/application_controller.rb +6 -6
- data/app/controllers/comments_controller.rb +7 -5
- data/app/controllers/entities/contacts_controller.rb +4 -4
- data/app/controllers/entities/opportunities_controller.rb +3 -3
- data/app/controllers/entities_controller.rb +3 -2
- data/app/controllers/home_controller.rb +21 -14
- data/app/controllers/passwords_controller.rb +1 -1
- data/app/controllers/users_controller.rb +3 -3
- data/app/helpers/accounts_helper.rb +2 -2
- data/app/helpers/application_helper.rb +20 -19
- data/app/helpers/campaigns_helper.rb +1 -1
- data/app/helpers/opportunities_helper.rb +4 -3
- data/app/helpers/tasks_helper.rb +6 -4
- data/app/helpers/users_helper.rb +1 -1
- data/app/helpers/versions_helper.rb +1 -1
- data/app/inputs/date_pair_input.rb +1 -1
- data/app/inputs/date_time_input.rb +1 -1
- data/app/models/entities/contact.rb +1 -0
- data/app/models/entities/lead.rb +4 -9
- data/app/models/entities/opportunity.rb +3 -6
- data/app/models/fields/field.rb +2 -3
- data/app/models/polymorphic/address.rb +1 -1
- data/app/models/polymorphic/comment.rb +1 -1
- data/app/models/polymorphic/task.rb +2 -3
- data/app/models/polymorphic/version.rb +5 -5
- data/app/models/setting.rb +6 -7
- data/app/models/users/user.rb +2 -2
- data/app/views/shared/_tags.html.haml +1 -5
- data/config/environments/test.rb +1 -1
- data/config/initializers/assets.rb +1 -1
- data/config/initializers/paper_trail.rb +1 -1
- data/config/initializers/simple_form.rb +1 -1
- data/config/initializers/views.rb +0 -1
- data/config/locales/th.rb +4 -4
- data/config/unicorn.rb +2 -2
- data/db/migrate/20100928030620_remove_uuid.rb +2 -4
- data/db/migrate/20111201030535_add_field_groups_klass_name.rb +2 -1
- data/db/migrate/20120224073107_remove_default_value_and_clear_settings.rb +1 -1
- data/db/schema.rb +0 -2
- data/fat_free_crm.gemspec +5 -5
- data/lib/fat_free_crm.rb +1 -3
- data/lib/fat_free_crm/callback.rb +2 -1
- data/lib/fat_free_crm/core_ext/string.rb +2 -2
- data/lib/fat_free_crm/engine.rb +1 -1
- data/lib/fat_free_crm/fields.rb +1 -1
- data/lib/fat_free_crm/i18n.rb +1 -1
- data/lib/fat_free_crm/mail_processor/base.rb +8 -2
- data/lib/fat_free_crm/mail_processor/comment_replies.rb +2 -1
- data/lib/fat_free_crm/permissions.rb +1 -1
- data/lib/fat_free_crm/version.rb +1 -1
- data/lib/gravatar_image_tag.rb +2 -2
- data/lib/tasks/ffcrm/comment_replies.rake +2 -2
- data/lib/tasks/ffcrm/config.rake +7 -6
- data/lib/tasks/ffcrm/demo.rake +1 -1
- data/lib/tasks/ffcrm/dropbox.rake +2 -2
- data/lib/tasks/ffcrm/setup.rake +4 -2
- data/lib/tasks/ffcrm/update_data.rake +5 -7
- data/spec/controllers/entities/campaigns_controller_spec.rb +1 -1
- data/spec/controllers/entities/leads_controller_spec.rb +1 -1
- data/spec/controllers/home_controller_spec.rb +5 -5
- data/spec/controllers/tasks_controller_spec.rb +3 -2
- data/spec/factories/sequences.rb +1 -2
- data/spec/factories/shared_factories.rb +5 -5
- data/spec/factories/user_factories.rb +3 -3
- data/spec/models/entities/opportunity_spec.rb +1 -1
- data/spec/models/fields/custom_field_pair_spec.rb +2 -2
- data/spec/models/setting_spec.rb +1 -1
- data/spec/shared/controllers.rb +1 -1
- data/spec/support/auth_macros.rb +6 -5
- data/spec/support/macros.rb +1 -1
- data/spec/views/application/auto_complete.haml_spec.rb +3 -3
- data/spec/views/campaigns/show.haml_spec.rb +2 -2
- data/spec/views/leads/update.js.haml_spec.rb +1 -1
- data/spec/views/tasks/index.haml_spec.rb +1 -1
- data/spec/views/tasks/update.js.haml_spec.rb +7 -7
- metadata +29 -4
data/README.md
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# Fat Free CRM [![TravisCI][travis-img-url]][travis-ci-url] [](https://codeclimate.com/github/fatfreecrm/fat_free_crm)
|
2
2
|
|
3
|
-
[travis-img-url]: https://secure.travis-ci.org/
|
4
|
-
[travis-ci-url]: https://travis-ci.org/
|
3
|
+
[travis-img-url]: https://secure.travis-ci.org/fatfreecrm/fat_free_crm.png?branch=master
|
4
|
+
[travis-ci-url]: https://travis-ci.org/fatfreecrm/fat_free_crm
|
5
5
|
|
6
6
|
### An open source, Ruby on Rails [customer relationship management][crm-wiki] platform (CRM).
|
7
7
|
|
@@ -48,13 +48,6 @@ Pull requests and bug reports are always welcome!
|
|
48
48
|
|
49
49
|
Visit our website at http://www.fatfreecrm.com/
|
50
50
|
|
51
|
-
## Usage
|
52
|
-
To use this; simply add to your Gemfile
|
53
|
-
```
|
54
|
-
gem 'fat_free_crm'
|
55
|
-
```
|
56
|
-
|
57
|
-
|
58
51
|
|
59
52
|
## System Requirements
|
60
53
|
|
@@ -45,7 +45,7 @@ class ApplicationController < ActionController::Base
|
|
45
45
|
respond_to do |format|
|
46
46
|
format.any(:js, :html) { render partial: 'auto_complete' }
|
47
47
|
format.json do
|
48
|
-
render json: @auto_complete.
|
48
|
+
render json: @auto_complete.each_with_object({}) { |a, h|
|
49
49
|
h[a.id] = a.respond_to?(:full_name) ? h(a.full_name) : h(a.name); h
|
50
50
|
}
|
51
51
|
end
|
@@ -251,10 +251,10 @@ class ApplicationController < ActionController::Base
|
|
251
251
|
#----------------------------------------------------------------------------
|
252
252
|
def redirection_url
|
253
253
|
# Try to redirect somewhere sensible. Note: not all controllers have an index action
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
254
|
+
if current_user.present?
|
255
|
+
respond_to?(:index) && action_name != 'index' ? { action: 'index' } : root_url
|
256
|
+
else
|
257
|
+
login_url
|
258
258
|
end
|
259
259
|
end
|
260
260
|
|
@@ -272,7 +272,7 @@ class ApplicationController < ActionController::Base
|
|
272
272
|
headers['Access-Control-Allow-Headers'] = 'X-Requested-With, X-Prototype-Version, Token'
|
273
273
|
headers['Access-Control-Max-Age'] = '1728000'
|
274
274
|
|
275
|
-
render :
|
275
|
+
render text: '', content_type: 'text/plain'
|
276
276
|
end
|
277
277
|
end
|
278
278
|
end
|
@@ -34,7 +34,8 @@ class CommentsController < ApplicationController
|
|
34
34
|
def edit
|
35
35
|
@comment = Comment.find(params[:id])
|
36
36
|
|
37
|
-
model
|
37
|
+
model = @comment.commentable_type
|
38
|
+
id = @comment.commentable_id
|
38
39
|
unless model.constantize.my.find_by_id(id)
|
39
40
|
respond_to_related_not_found(model.downcase)
|
40
41
|
end
|
@@ -49,12 +50,13 @@ class CommentsController < ApplicationController
|
|
49
50
|
comment_params.merge(user_id: current_user.id)
|
50
51
|
)
|
51
52
|
# Make sure commentable object exists and is accessible to the current user.
|
52
|
-
model
|
53
|
-
|
54
|
-
|
55
|
-
else
|
53
|
+
model = @comment.commentable_type
|
54
|
+
id = @comment.commentable_id
|
55
|
+
if model.constantize.my.find_by_id(id)
|
56
56
|
@comment.save
|
57
57
|
respond_with(@comment)
|
58
|
+
else
|
59
|
+
respond_to_related_not_found(model.downcase)
|
58
60
|
end
|
59
61
|
end
|
60
62
|
|
@@ -65,14 +65,14 @@ class ContactsController < EntitiesController
|
|
65
65
|
@contact.add_comment_by_user(@comment_body, current_user)
|
66
66
|
@contacts = get_contacts if called_from_index_page?
|
67
67
|
else
|
68
|
-
|
69
|
-
@account = Account.find(params[:account][:id])
|
70
|
-
else
|
68
|
+
if params[:account][:id].blank?
|
71
69
|
if request.referer =~ /\/accounts\/(\d+)\z/
|
72
70
|
@account = Account.find(Regexp.last_match[1]) # related account
|
73
71
|
else
|
74
72
|
@account = Account.new(user: current_user)
|
75
73
|
end
|
74
|
+
else
|
75
|
+
@account = Account.find(params[:account][:id])
|
76
76
|
end
|
77
77
|
@opportunity = Opportunity.my.find(params[:opportunity]) unless params[:opportunity].blank?
|
78
78
|
end
|
@@ -153,7 +153,7 @@ class ContactsController < EntitiesController
|
|
153
153
|
|
154
154
|
def set_options
|
155
155
|
super
|
156
|
-
@naming = (current_user.pref[:contacts_naming]
|
156
|
+
@naming = (current_user.pref[:contacts_naming] || Contact.first_name_position) unless params[:cancel].true?
|
157
157
|
end
|
158
158
|
|
159
159
|
#----------------------------------------------------------------------------
|
@@ -79,14 +79,14 @@ class OpportunitiesController < EntitiesController
|
|
79
79
|
end
|
80
80
|
else
|
81
81
|
@accounts = Account.my.order('name')
|
82
|
-
|
83
|
-
@account = Account.find(params[:account][:id])
|
84
|
-
else
|
82
|
+
if params[:account][:id].blank?
|
85
83
|
if request.referer =~ /\/accounts\/(\d+)\z/
|
86
84
|
@account = Account.find(Regexp.last_match[1]) # related account
|
87
85
|
else
|
88
86
|
@account = Account.new(user: current_user)
|
89
87
|
end
|
88
|
+
else
|
89
|
+
@account = Account.find(params[:account][:id])
|
90
90
|
end
|
91
91
|
@contact = Contact.find(params[:contact]) unless params[:contact].blank?
|
92
92
|
@campaign = Campaign.find(params[:campaign]) unless params[:campaign].blank?
|
@@ -186,7 +186,8 @@ class EntitiesController < ApplicationController
|
|
186
186
|
#----------------------------------------------------------------------------
|
187
187
|
def parse_query_and_tags(search_string)
|
188
188
|
return ['', ''] if search_string.blank?
|
189
|
-
query
|
189
|
+
query = []
|
190
|
+
tags = []
|
190
191
|
search_string.strip.split(/\s+/).each do |token|
|
191
192
|
if token.starts_with?("#")
|
192
193
|
tags << token[1..-1]
|
@@ -207,7 +208,7 @@ class EntitiesController < ApplicationController
|
|
207
208
|
def set_view
|
208
209
|
if params['view']
|
209
210
|
controller = params['controller']
|
210
|
-
action =
|
211
|
+
action = params['action'] == 'show' ? 'show' : 'index' # create update redraw filter index actions all use index view
|
211
212
|
current_user.pref[:"#{controller}_#{action}_view"] = params['view']
|
212
213
|
end
|
213
214
|
end
|
@@ -126,23 +126,30 @@ class HomeController < ApplicationController
|
|
126
126
|
# needs refactoring to use user id instead. Permuations based on name or email
|
127
127
|
# yield incorrect results.
|
128
128
|
def activity_user
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
end
|
141
|
-
end
|
142
|
-
end
|
129
|
+
return nil if current_user.pref[:activity_user] == "all_users"
|
130
|
+
return nil unless current_user.pref[:activity_user]
|
131
|
+
|
132
|
+
is_email = current_user.pref[:activity_user].include?("@")
|
133
|
+
|
134
|
+
user = if is_email
|
135
|
+
User.where(email: current_user.pref[:activity_user]).first
|
136
|
+
else # first_name middle_name last_name any_name
|
137
|
+
name_query(current_user.pref[:activity_user])
|
138
|
+
end
|
139
|
+
|
143
140
|
user.is_a?(User) ? user.id : nil
|
144
141
|
end
|
145
142
|
|
143
|
+
def name_query(user)
|
144
|
+
if user.include?(" ")
|
145
|
+
user.name_permutations.map do |first, last|
|
146
|
+
User.where(first_name: first, last_name: last)
|
147
|
+
end.map(&:to_a).flatten.first
|
148
|
+
else
|
149
|
+
[User.where(first_name: user), User.where(last_name: user)].map(&:to_a).flatten.first
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
146
153
|
#----------------------------------------------------------------------------
|
147
154
|
def activity_duration
|
148
155
|
duration = current_user.pref[:activity_duration]
|
@@ -60,6 +60,6 @@ class PasswordsController < ApplicationController
|
|
60
60
|
#----------------------------------------------------------------------------
|
61
61
|
def empty_password?
|
62
62
|
(params[:user][:password] == params[:user][:password_confirmation]) &&
|
63
|
-
|
63
|
+
params[:user][:password].blank? # " ".blank? == true
|
64
64
|
end
|
65
65
|
end
|
@@ -102,13 +102,13 @@ class UsersController < ApplicationController
|
|
102
102
|
#----------------------------------------------------------------------------
|
103
103
|
def change_password
|
104
104
|
if @user.valid_password?(params[:current_password], true) || @user.password_hash.blank?
|
105
|
-
|
105
|
+
if params[:user][:password].blank?
|
106
|
+
flash[:notice] = t(:msg_password_not_changed)
|
107
|
+
else
|
106
108
|
@user.password = params[:user][:password]
|
107
109
|
@user.password_confirmation = params[:user][:password_confirmation]
|
108
110
|
@user.save
|
109
111
|
flash[:notice] = t(:msg_password_changed)
|
110
|
-
else
|
111
|
-
flash[:notice] = t(:msg_password_not_changed)
|
112
112
|
end
|
113
113
|
else
|
114
114
|
@user.errors.add(:current_password, t(:msg_invalid_password))
|
@@ -28,8 +28,8 @@ module AccountsHelper
|
|
28
28
|
options[:selected] = (@account && @account.id) || 0
|
29
29
|
accounts = ([@account] + Account.my.order(:name).limit(25)).compact.uniq
|
30
30
|
collection_select :account, :id, accounts, :id, :name, options,
|
31
|
-
|
32
|
-
|
31
|
+
"data-placeholder": t(:select_an_account),
|
32
|
+
"data-url": auto_complete_accounts_path(format: 'json'),
|
33
33
|
style: "width:330px; display:none;",
|
34
34
|
class: 'ajax_chosen'
|
35
35
|
end
|
@@ -10,14 +10,14 @@ module ApplicationHelper
|
|
10
10
|
@current_tab ||= tabs.first[:text] # Select first tab by default.
|
11
11
|
tabs.each { |tab| tab[:active] = (@current_tab == tab[:text] || @current_tab == tab[:url][:controller]) }
|
12
12
|
else
|
13
|
-
|
13
|
+
raise FatFreeCRM::MissingSettings, "Tab settings are missing, please run <b>rake ffcrm:setup</b> command."
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
17
|
#----------------------------------------------------------------------------
|
18
18
|
def tabless_layout?
|
19
19
|
%w(authentications passwords).include?(controller.controller_name) ||
|
20
|
-
((controller.controller_name == "users") &&
|
20
|
+
((controller.controller_name == "users") && %w(create new).include?(controller.action_name))
|
21
21
|
end
|
22
22
|
|
23
23
|
# Show existing flash or embed hidden paragraph ready for flash[:notice]
|
@@ -36,7 +36,7 @@ module ApplicationHelper
|
|
36
36
|
#----------------------------------------------------------------------------
|
37
37
|
def subtitle(id, hidden = true, text = id.to_s.split("_").last.capitalize)
|
38
38
|
content_tag("div",
|
39
|
-
link_to("<small>#{
|
39
|
+
link_to("<small>#{hidden ? '►' : '▼'}</small> #{sanitize text}".html_safe,
|
40
40
|
url_for(controller: :home, action: :toggle, id: id),
|
41
41
|
remote: true,
|
42
42
|
onclick: "crm.flip_subtitle(this)"
|
@@ -244,7 +244,7 @@ module ApplicationHelper
|
|
244
244
|
#----------------------------------------------------------------------------
|
245
245
|
def refresh_sidebar_for(view, action = nil, shake = nil)
|
246
246
|
text = ""
|
247
|
-
text << "$('#sidebar').html('#{
|
247
|
+
text << "$('#sidebar').html('#{j render(partial: 'layouts/sidebar', locals: { view: view, action: action })}');"
|
248
248
|
text << "$('##{j shake.to_s}').effect('shake', { duration:200, distance: 3 });" if shake
|
249
249
|
text.html_safe
|
250
250
|
end
|
@@ -258,9 +258,9 @@ module ApplicationHelper
|
|
258
258
|
if site == :skype
|
259
259
|
url = "callto:" << url
|
260
260
|
else
|
261
|
-
url = "http://" << url unless url
|
261
|
+
url = "http://" << url unless url =~ /^https?:\/\//
|
262
262
|
end
|
263
|
-
link_to(image_tag("#{site}.gif", size: "15x15"), h(url),
|
263
|
+
link_to(image_tag("#{site}.gif", size: "15x15"), h(url), "data-popup": true, title: t(:open_in_window, h(url)))
|
264
264
|
end
|
265
265
|
end.compact.join("\n").html_safe
|
266
266
|
end
|
@@ -269,7 +269,8 @@ module ApplicationHelper
|
|
269
269
|
#----------------------------------------------------------------------------
|
270
270
|
def redraw(option, value, url = send("redraw_#{controller.controller_name}_path"))
|
271
271
|
if value.is_a?(Array)
|
272
|
-
param
|
272
|
+
param = value.first
|
273
|
+
value = value.last
|
273
274
|
end
|
274
275
|
%{
|
275
276
|
if ($('##{option}').html() != '#{value}') {
|
@@ -361,11 +362,11 @@ module ApplicationHelper
|
|
361
362
|
def links_to_export(action = :index)
|
362
363
|
token = current_user.single_access_token
|
363
364
|
url_params = { action: action }
|
364
|
-
url_params
|
365
|
-
url_params
|
366
|
-
url_params
|
367
|
-
url_params
|
368
|
-
url_params
|
365
|
+
url_params[:id] = params[:id] unless params[:id].blank?
|
366
|
+
url_params[:query] = params[:query] unless params[:query].blank?
|
367
|
+
url_params[:q] = params[:q] unless params[:q].blank?
|
368
|
+
url_params[:view] = @view unless @view.blank? # tasks
|
369
|
+
url_params[:id] = params[:id] unless params[:id].blank?
|
369
370
|
|
370
371
|
exports = %w(xls csv).map do |format|
|
371
372
|
link_to(format.upcase, url_params.merge(format: format), title: I18n.t(:"to_#{format}")) unless action.to_s == "show"
|
@@ -439,7 +440,7 @@ module ApplicationHelper
|
|
439
440
|
def section_title(id, hidden = true, text = nil, info_text = nil)
|
440
441
|
text = id.to_s.split("_").last.capitalize if text.nil?
|
441
442
|
content_tag("div", class: "subtitle show_attributes") do
|
442
|
-
content = link_to("<small>#{
|
443
|
+
content = link_to("<small>#{hidden ? '►' : '▼'}</small> #{sanitize text}".html_safe,
|
443
444
|
url_for(controller: :home, action: :toggle, id: id),
|
444
445
|
remote: true,
|
445
446
|
onclick: "crm.flip_subtitle(this)"
|
@@ -452,7 +453,7 @@ module ApplicationHelper
|
|
452
453
|
# Return name of current view
|
453
454
|
def current_view_name
|
454
455
|
controller = params['controller']
|
455
|
-
action =
|
456
|
+
action = params['action'] == 'show' ? 'show' : 'index' # create update redraw filter index actions all use index view
|
456
457
|
current_user.pref[:"#{controller}_#{action}_view"]
|
457
458
|
end
|
458
459
|
|
@@ -460,7 +461,7 @@ module ApplicationHelper
|
|
460
461
|
# Get template in current context with current view name
|
461
462
|
def template_for_current_view
|
462
463
|
controller = params['controller']
|
463
|
-
action =
|
464
|
+
action = params['action'] == 'show' ? 'show' : 'index' # create update redraw filter index actions all use index view
|
464
465
|
template = FatFreeCRM::ViewFactory.template_for_current_view(controller: controller, action: action, name: current_view_name)
|
465
466
|
template
|
466
467
|
end
|
@@ -469,7 +470,7 @@ module ApplicationHelper
|
|
469
470
|
# Generate buttons for available views given the current context
|
470
471
|
def view_buttons
|
471
472
|
controller = params['controller']
|
472
|
-
action =
|
473
|
+
action = params['action'] == 'show' ? 'show' : 'index' # create update redraw filter index actions all use index view
|
473
474
|
views = FatFreeCRM::ViewFactory.views_for(controller: controller, action: action)
|
474
475
|
return nil unless views.size > 1
|
475
476
|
lis = ''.html_safe
|
@@ -481,8 +482,8 @@ module ApplicationHelper
|
|
481
482
|
"#{h view.name}-button"
|
482
483
|
end
|
483
484
|
lis << content_tag(:li) do
|
484
|
-
url =
|
485
|
-
link_to('#', title: t(view.name, default: h(view.title)),
|
485
|
+
url = action == "index" ? send("redraw_#{controller}_path") : send("#{controller.singularize}_path")
|
486
|
+
link_to('#', title: t(view.name, default: h(view.title)), "data-view": h(view.name), "data-url": h(url), "data-context": action, class: classes) do
|
486
487
|
icon = view.icon || 'fa-bars'
|
487
488
|
content_tag(:i, nil, class: "fa #{h icon}")
|
488
489
|
end
|
@@ -520,7 +521,7 @@ module ApplicationHelper
|
|
520
521
|
# options = { renderer: {...} , params: {...}
|
521
522
|
def paginate(options = {})
|
522
523
|
collection = options.delete(:collection)
|
523
|
-
options = { params: { action: 'index'}}.merge(options) if params['action'] == 'filter'
|
524
|
+
options = { params: { action: 'index' } }.merge(options) if params['action'] == 'filter'
|
524
525
|
options = { renderer: RemoteLinkPaginationHelper::LinkRenderer }.merge(options)
|
525
526
|
will_paginate(collection, options)
|
526
527
|
end
|
@@ -29,6 +29,6 @@ module CampaignsHelper
|
|
29
29
|
def campaign_summary(campaign)
|
30
30
|
status = render file: "campaigns/_status.html.haml", locals: { campaign: campaign }
|
31
31
|
metrics = render file: "campaigns/_metrics.html.haml", locals: { campaign: campaign }
|
32
|
-
"#{t(campaign.status)}, " << [status, metrics].map { |str| strip_tags(str) }.join(' ').
|
32
|
+
"#{t(campaign.status)}, " << [status, metrics].map { |str| strip_tags(str) }.join(' ').delete("\n")
|
33
33
|
end
|
34
34
|
end
|
@@ -13,7 +13,8 @@ module OpportunitiesHelper
|
|
13
13
|
# Opportunity summary for RSS/ATOM feeds.
|
14
14
|
#----------------------------------------------------------------------------
|
15
15
|
def opportunity_summary(opportunity)
|
16
|
-
summary
|
16
|
+
summary = []
|
17
|
+
amount = []
|
17
18
|
summary << (opportunity.stage ? t(opportunity.stage) : t(:other))
|
18
19
|
summary << number_to_currency(opportunity.weighted_amount, precision: 0)
|
19
20
|
unless %w(won lost).include?(opportunity.stage)
|
@@ -38,8 +39,8 @@ module OpportunitiesHelper
|
|
38
39
|
selected_campaign = Campaign.find_by_id(options[:selected])
|
39
40
|
campaigns = ([selected_campaign] + Campaign.my.order(:name).limit(25)).compact.uniq
|
40
41
|
collection_select :opportunity, :campaign_id, campaigns, :id, :name, options,
|
41
|
-
|
42
|
-
|
42
|
+
"data-placeholder": t(:select_a_campaign),
|
43
|
+
"data-url": auto_complete_campaigns_path(format: 'json'),
|
43
44
|
style: "width:330px; display:none;",
|
44
45
|
class: 'ajax_chosen'
|
45
46
|
end
|
data/app/helpers/tasks_helper.rb
CHANGED
@@ -92,23 +92,25 @@ module TasksHelper
|
|
92
92
|
|
93
93
|
#----------------------------------------------------------------------------
|
94
94
|
def replace_content(task, bucket = nil)
|
95
|
-
partial =
|
95
|
+
partial = task.assigned_to && task.assigned_to != current_user.id ? "assigned" : "pending"
|
96
96
|
html = render(partial: "tasks/#{partial}", collection: [task], locals: { bucket: bucket })
|
97
|
-
text = "$('##{dom_id(task)}').html('#{
|
97
|
+
text = "$('##{dom_id(task)}').html('#{j html}');\n".html_safe
|
98
|
+
|
99
|
+
text
|
98
100
|
end
|
99
101
|
|
100
102
|
#----------------------------------------------------------------------------
|
101
103
|
def insert_content(task, bucket, view)
|
102
104
|
text = "$('#list_#{bucket}').show();\n"
|
103
105
|
html = render(partial: view, collection: [task], locals: { bucket: bucket })
|
104
|
-
text << "$('##{h bucket.to_s}').prepend('#{
|
106
|
+
text << "$('##{h bucket.to_s}').prepend('#{j html}');\n"
|
105
107
|
text << "$('##{dom_id(task)}').effect('highlight', { duration:1500 });\n"
|
106
108
|
text.html_safe
|
107
109
|
end
|
108
110
|
|
109
111
|
#----------------------------------------------------------------------------
|
110
112
|
def tasks_flash(message)
|
111
|
-
text = "$('#flash').html('#{
|
113
|
+
text = "$('#flash').html('#{sanitize(message)}');\n"
|
112
114
|
text << "crm.flash('notice', true)\n"
|
113
115
|
text.html_safe
|
114
116
|
end
|
data/app/helpers/users_helper.rb
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
module UsersHelper
|
7
7
|
def language_for(user)
|
8
8
|
if user.preference[:locale]
|
9
|
-
|
9
|
+
_locale, language = languages.detect { |locale, _language| locale == user.preference[:locale] }
|
10
10
|
end
|
11
11
|
language || "English"
|
12
12
|
end
|