fat_free_crm 0.15.0.beta → 0.15.0.beta.2
Sign up to get free protection for your applications and to get access to all the features.
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] [![Code Climate](https://codeclimate.com/github/fatfreecrm/fat_free_crm.png)](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
|