fat_free_crm 0.11.1 → 0.11.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.
- data/Gemfile +30 -12
- data/Gemfile.lock +131 -119
- data/Procfile +1 -1
- data/README.md +1 -1
- data/app/assets/images/notifications.png +0 -0
- data/app/assets/javascripts/application.js.erb +3 -0
- data/app/assets/javascripts/crm_textarea_autocomplete.js +44 -0
- data/app/assets/stylesheets/application.css.erb +2 -0
- data/app/assets/stylesheets/common.scss +7 -11
- data/app/assets/stylesheets/textarea_autocomplete.scss +42 -0
- data/app/controllers/admin/application_controller.rb +5 -5
- data/app/controllers/admin/field_groups_controller.rb +11 -51
- data/app/controllers/admin/fields_controller.rb +13 -59
- data/app/controllers/admin/plugins_controller.rb +1 -4
- data/app/controllers/admin/settings_controller.rb +0 -4
- data/app/controllers/admin/tags_controller.rb +11 -66
- data/app/controllers/admin/users_controller.rb +20 -83
- data/app/controllers/application_controller.rb +83 -69
- data/app/controllers/comments_controller.rb +12 -29
- data/app/controllers/emails_controller.rb +1 -5
- data/app/controllers/entities/accounts_controller.rb +13 -32
- data/app/controllers/entities/campaigns_controller.rb +17 -32
- data/app/controllers/entities/contacts_controller.rb +20 -38
- data/app/controllers/entities/leads_controller.rb +33 -55
- data/app/controllers/entities/opportunities_controller.rb +26 -42
- data/app/controllers/entities_controller.rb +92 -83
- data/app/controllers/home_controller.rb +1 -10
- data/app/controllers/lists_controller.rb +1 -4
- data/app/controllers/{entities/tasks_controller.rb → tasks_controller.rb} +21 -32
- data/app/controllers/users_controller.rb +6 -5
- data/app/helpers/accounts_helper.rb +32 -9
- data/app/helpers/application_helper.rb +15 -1
- data/app/helpers/campaigns_helper.rb +1 -1
- data/app/helpers/comments_helper.rb +11 -1
- data/app/helpers/leads_helper.rb +1 -1
- data/app/helpers/opportunities_helper.rb +1 -1
- data/app/{models/mailers/notifier.rb → mailers/dropbox_mailer.rb} +5 -16
- data/app/mailers/subscription_mailer.rb +37 -0
- data/{lib/tasks/dropbox.rake → app/mailers/user_mailer.rb} +11 -13
- data/app/models/entities/account.rb +3 -1
- data/app/models/entities/campaign.rb +3 -1
- data/app/models/entities/contact.rb +3 -1
- data/app/models/entities/lead.rb +6 -5
- data/app/models/entities/opportunity.rb +3 -1
- data/app/models/fields/field.rb +1 -1
- data/app/models/polymorphic/comment.rb +34 -0
- data/app/models/{entities → polymorphic}/task.rb +16 -3
- data/app/models/setting.rb +15 -15
- data/app/models/users/ability.rb +12 -5
- data/app/models/users/user.rb +7 -2
- data/app/views/accounts/index.html.haml +1 -1
- data/app/views/accounts/index.js.rjs +1 -1
- data/app/views/admin/plugins/index.html.haml +1 -7
- data/app/views/{shared/auto_complete.html.haml → application/_auto_complete.html.haml} +0 -0
- data/app/views/{shared → application}/index.atom.builder +1 -1
- data/app/views/{shared → application}/index.rss.builder +1 -1
- data/app/views/campaigns/index.html.haml +1 -1
- data/app/views/campaigns/index.js.rjs +1 -1
- data/app/views/comments/_new.html.haml +6 -0
- data/app/views/comments/_subscription_links.html.haml +13 -0
- data/app/views/comments/new.js.rjs +2 -0
- data/app/views/contacts/_top_section.html.haml +3 -13
- data/app/views/contacts/index.html.haml +1 -1
- data/app/views/contacts/index.js.rjs +1 -1
- data/app/views/{notifier/dropbox_ack_notification.html.haml → dropbox_mailer/dropbox_notification.html.haml} +2 -2
- data/app/views/{shared → entities}/attach.js.rjs +1 -1
- data/app/views/entities/contacts.js.rjs +1 -1
- data/app/views/{shared/discard.rjs → entities/discard.js.rjs} +0 -0
- data/app/views/entities/leads.js.rjs +1 -1
- data/app/views/entities/opportunities.js.rjs +1 -1
- data/app/views/entities/subscription_update.js.rjs +4 -0
- data/app/views/entities/versions.js.rjs +1 -1
- data/app/views/layouts/_footer.html.haml +1 -1
- data/app/views/layouts/application.html.haml +3 -0
- data/app/views/leads/_contact.html.haml +1 -0
- data/app/views/leads/index.html.haml +1 -1
- data/app/views/leads/index.js.rjs +1 -1
- data/app/views/opportunities/_top_section.html.haml +4 -14
- data/app/views/opportunities/index.html.haml +1 -1
- data/app/views/opportunities/index.js.rjs +1 -1
- data/app/views/subscription_mailer/comment_notification.text.erb +7 -0
- data/app/views/{notifier → user_mailer}/password_reset_instructions.html.haml +0 -0
- data/config/application.rb +3 -1
- data/config/environments/development.rb +1 -1
- data/config/environments/test.rb +3 -0
- data/config/initializers/action_mailer.rb +8 -5
- data/config/initializers/cancan.rb +151 -0
- data/config/initializers/constants.rb +1 -0
- data/config/initializers/locale.rb +20 -0
- data/config/initializers/paper_trail.rb +4 -5
- data/config/initializers/relative_url_root.rb +0 -1
- data/config/initializers/squeel.rb +5 -0
- data/config/locales/cz_fat_free_crm.yml +3 -3
- data/config/locales/de.yml +2 -2
- data/config/locales/de_fat_free_crm.yml +651 -596
- data/config/locales/en-GB_fat_free_crm.yml +3 -3
- data/config/locales/en-US_fat_free_crm.yml +13 -3
- data/config/locales/es_fat_free_crm.yml +3 -3
- data/config/locales/fr-CA_fat_free_crm.yml +3 -3
- data/config/locales/fr_fat_free_crm.yml +3 -3
- data/config/locales/it_fat_free_crm.yml +3 -3
- data/config/locales/pl_fat_free_crm.yml +3 -3
- data/config/locales/pt-BR_fat_free_crm.yml +3 -3
- data/config/locales/ru_fat_free_crm.yml +3 -3
- data/config/locales/sv-SE_fat_free_crm.yml +3 -3
- data/config/locales/th_fat_free_crm.yml +3 -3
- data/config/routes.rb +10 -0
- data/config/settings.default.yml +29 -10
- data/config/unicorn.rb +4 -0
- data/db/migrate/20111201030535_add_field_groups_klass_name.rb +3 -1
- data/db/migrate/20120314080441_add_subscribed_users_to_entities.rb +23 -0
- data/db/migrate/20120405080727_change_subscribed_users_to_set.rb +24 -0
- data/db/migrate/20120405080742_change_further_subscribed_users_to_set.rb +27 -0
- data/db/migrate/20120413034923_add_index_on_versions_item_type.rb +5 -0
- data/db/schema.rb +109 -126
- data/fat_free_crm.gemspec +12 -18
- data/lib/fat_free_crm.rb +0 -1
- data/lib/fat_free_crm/core_ext/array.rb +1 -0
- data/lib/fat_free_crm/gem_dependencies.rb +1 -0
- data/lib/fat_free_crm/mail_processor/base.rb +226 -0
- data/lib/fat_free_crm/mail_processor/comment_replies.rb +86 -0
- data/lib/fat_free_crm/mail_processor/dropbox.rb +288 -0
- data/lib/fat_free_crm/permissions.rb +6 -19
- data/lib/fat_free_crm/renderers.rb +0 -8
- data/lib/fat_free_crm/tabs.rb +1 -1
- data/lib/fat_free_crm/version.rb +1 -1
- data/lib/plugins/country_select/lib/country_select.rb +2 -2
- data/lib/tasks/mail_processing.rake +60 -0
- data/spec/controllers/admin/users_controller_spec.rb +0 -2
- data/spec/controllers/{accounts_controller_spec.rb → entities/accounts_controller_spec.rb} +7 -9
- data/spec/controllers/{campaigns_controller_spec.rb → entities/campaigns_controller_spec.rb} +7 -7
- data/spec/controllers/{contacts_controller_spec.rb → entities/contacts_controller_spec.rb} +5 -9
- data/spec/controllers/{leads_controller_spec.rb → entities/leads_controller_spec.rb} +7 -9
- data/spec/controllers/{opportunities_controller_spec.rb → entities/opportunities_controller_spec.rb} +8 -15
- data/spec/controllers/tasks_controller_spec.rb +1 -5
- data/spec/controllers/users_controller_spec.rb +5 -9
- data/spec/factories/subscription_factories.rb +6 -0
- data/spec/lib/mail_processor/base_spec.rb +164 -0
- data/spec/lib/mail_processor/comment_replies_spec.rb +63 -0
- data/spec/lib/{dropbox_spec.rb → mail_processor/dropbox_spec.rb} +73 -181
- data/spec/lib/mail_processor/sample_emails/dropbox.rb +167 -0
- data/spec/mailers/subscription_mailer_spec.rb +17 -0
- data/spec/models/{base → entities}/account_contact_spec.rb +0 -0
- data/spec/models/{base → entities}/account_opportunity_spec.rb +0 -0
- data/spec/models/{base → entities}/account_spec.rb +4 -0
- data/spec/models/{base → entities}/campaign_spec.rb +4 -0
- data/spec/models/{base → entities}/contact_opportunity_spec.rb +0 -0
- data/spec/models/{base → entities}/contact_spec.rb +4 -0
- data/spec/models/{base → entities}/lead_spec.rb +4 -0
- data/spec/models/{base → entities}/opportunity_spec.rb +4 -0
- data/spec/models/polymorphic/comment_spec.rb +15 -0
- data/spec/models/{base → polymorphic}/task_spec.rb +124 -30
- data/spec/models/polymorphic/version_spec.rb +1 -1
- data/spec/shared/controllers.rb +5 -7
- data/spec/shared/models.rb +46 -0
- data/spec/spec_helper.rb +3 -4
- data/spec/support/mail_processor_mocks.rb +30 -0
- data/spec/support/uploaded_file.rb +3 -0
- data/spec/views/{common → application}/auto_complete.haml_spec.rb +1 -1
- data/vendor/assets/images/jquery-ui/ui-bg_diagonals-thick_18_b81900_40x40.png +0 -0
- data/vendor/assets/images/jquery-ui/ui-bg_diagonals-thick_20_666666_40x40.png +0 -0
- data/vendor/assets/images/jquery-ui/ui-bg_flat_10_000000_40x100.png +0 -0
- data/vendor/assets/images/jquery-ui/ui-bg_glass_100_f6f6f6_1x400.png +0 -0
- data/vendor/assets/images/jquery-ui/ui-bg_glass_100_fdf5ce_1x400.png +0 -0
- data/vendor/assets/images/jquery-ui/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/vendor/assets/images/jquery-ui/ui-bg_gloss-wave_35_f6a828_500x100.png +0 -0
- data/vendor/assets/images/jquery-ui/ui-bg_highlight-soft_100_eeeeee_1x100.png +0 -0
- data/vendor/assets/images/jquery-ui/ui-bg_highlight-soft_75_ffe45c_1x100.png +0 -0
- data/vendor/assets/images/jquery-ui/ui-icons_222222_256x240.png +0 -0
- data/vendor/assets/images/jquery-ui/ui-icons_228ef1_256x240.png +0 -0
- data/vendor/assets/images/jquery-ui/ui-icons_ef8c08_256x240.png +0 -0
- data/vendor/assets/images/jquery-ui/ui-icons_ffd27a_256x240.png +0 -0
- data/vendor/assets/images/jquery-ui/ui-icons_ffffff_256x240.png +0 -0
- data/vendor/assets/javascripts/textarea_autocomplete.js +605 -0
- data/vendor/assets/stylesheets/jquery-ui.custom.css.erb +565 -0
- metadata +234 -154
- data/config/locales/simple_form.en.yml +0 -24
- data/lib/fat_free_crm/dropbox.rb +0 -439
- data/spec/lib/dropbox/email_samples.rb +0 -77
@@ -28,57 +28,51 @@ class LeadsController < EntitiesController
|
|
28
28
|
# GET /leads/1
|
29
29
|
#----------------------------------------------------------------------------
|
30
30
|
def show
|
31
|
-
@lead = Lead.my.find(params[:id])
|
32
|
-
|
33
31
|
respond_with(@lead) do |format|
|
34
32
|
format.html do
|
35
33
|
@comment = Comment.new
|
36
34
|
@timeline = timeline(@lead)
|
37
35
|
end
|
38
36
|
end
|
39
|
-
|
40
|
-
rescue ActiveRecord::RecordNotFound
|
41
|
-
respond_to_not_found(:html, :json, :xml)
|
42
37
|
end
|
43
38
|
|
44
39
|
# GET /leads/new
|
45
40
|
#----------------------------------------------------------------------------
|
46
41
|
def new
|
47
|
-
@lead =
|
42
|
+
@lead.attributes = {:user => @current_user, :access => Setting.default_access}
|
48
43
|
@users = User.except(@current_user)
|
49
|
-
|
44
|
+
get_campaigns
|
45
|
+
|
50
46
|
if params[:related]
|
51
|
-
model, id = params[:related].split(
|
52
|
-
|
47
|
+
model, id = params[:related].split('_')
|
48
|
+
if related = model.classify.constantize.my.find_by_id(id)
|
49
|
+
instance_variable_set("@#{model}", related)
|
50
|
+
else
|
51
|
+
respond_to_related_not_found(model) and return
|
52
|
+
end
|
53
53
|
end
|
54
|
-
respond_with(@lead)
|
55
54
|
|
56
|
-
|
57
|
-
respond_to_related_not_found(model, :js) if model
|
55
|
+
respond_with(@lead)
|
58
56
|
end
|
59
57
|
|
60
58
|
# GET /leads/1/edit AJAX
|
61
59
|
#----------------------------------------------------------------------------
|
62
60
|
def edit
|
63
|
-
@lead = Lead.my.find(params[:id])
|
64
61
|
@users = User.except(@current_user)
|
65
|
-
|
62
|
+
get_campaigns
|
63
|
+
|
66
64
|
if params[:previous].to_s =~ /(\d+)\z/
|
67
|
-
@previous = Lead.my.
|
65
|
+
@previous = Lead.my.find_by_id($1) || $1.to_i
|
68
66
|
end
|
69
|
-
respond_with(@lead)
|
70
67
|
|
71
|
-
|
72
|
-
@previous ||= $1.to_i
|
73
|
-
respond_to_not_found(:js) unless @lead
|
68
|
+
respond_with(@lead)
|
74
69
|
end
|
75
70
|
|
76
71
|
# POST /leads
|
77
72
|
#----------------------------------------------------------------------------
|
78
73
|
def create
|
79
|
-
@lead = Lead.new(params[:lead])
|
80
74
|
@users = User.except(@current_user)
|
81
|
-
|
75
|
+
get_campaigns
|
82
76
|
|
83
77
|
respond_with(@lead) do |format|
|
84
78
|
if @lead.save_with_permissions(params)
|
@@ -95,61 +89,48 @@ class LeadsController < EntitiesController
|
|
95
89
|
# PUT /leads/1
|
96
90
|
#----------------------------------------------------------------------------
|
97
91
|
def update
|
98
|
-
@lead = Lead.my.find(params[:id])
|
99
|
-
|
100
92
|
respond_with(@lead) do |format|
|
101
93
|
if @lead.update_with_permissions(params[:lead], params[:users])
|
102
94
|
update_sidebar
|
103
95
|
else
|
104
96
|
@users = User.except(@current_user)
|
105
|
-
@campaigns = Campaign.my.order(
|
97
|
+
@campaigns = Campaign.my.order('name')
|
106
98
|
end
|
107
99
|
end
|
108
|
-
|
109
|
-
rescue ActiveRecord::RecordNotFound
|
110
|
-
respond_to_not_found(:js, :json, :xml)
|
111
100
|
end
|
112
101
|
|
113
102
|
# DELETE /leads/1
|
114
103
|
#----------------------------------------------------------------------------
|
115
104
|
def destroy
|
116
|
-
@lead
|
117
|
-
@lead.destroy if @lead
|
105
|
+
@lead.destroy
|
118
106
|
|
119
107
|
respond_with(@lead) do |format|
|
120
108
|
format.html { respond_to_destroy(:html) }
|
121
109
|
format.js { respond_to_destroy(:ajax) }
|
122
110
|
end
|
123
|
-
|
124
|
-
rescue ActiveRecord::RecordNotFound
|
125
|
-
respond_to_not_found(:html, :js, :json, :xml)
|
126
111
|
end
|
127
112
|
|
128
113
|
# GET /leads/1/convert
|
129
114
|
#----------------------------------------------------------------------------
|
130
115
|
def convert
|
131
|
-
@lead = Lead.my.find(params[:id])
|
132
116
|
@users = User.except(@current_user)
|
133
117
|
@account = Account.new(:user => @current_user, :name => @lead.company, :access => "Lead")
|
134
|
-
@accounts = Account.my.order(
|
118
|
+
@accounts = Account.my.order('name')
|
135
119
|
@opportunity = Opportunity.new(:user => @current_user, :access => "Lead", :stage => "prospecting", :campaign => @lead.campaign, :source => @lead.source)
|
120
|
+
|
136
121
|
if params[:previous].to_s =~ /(\d+)\z/
|
137
|
-
@previous = Lead.my.
|
122
|
+
@previous = Lead.my.find_by_id($1) || $1.to_i
|
138
123
|
end
|
139
|
-
respond_with(@lead)
|
140
124
|
|
141
|
-
|
142
|
-
@previous ||= $1.to_i
|
143
|
-
respond_to_not_found(:js, :json, :xml) unless @lead
|
125
|
+
respond_with(@lead)
|
144
126
|
end
|
145
127
|
|
146
128
|
# PUT /leads/1/promote
|
147
129
|
#----------------------------------------------------------------------------
|
148
130
|
def promote
|
149
|
-
@lead = Lead.my.find(params[:id])
|
150
131
|
@users = User.except(@current_user)
|
151
132
|
@account, @opportunity, @contact = @lead.promote(params)
|
152
|
-
@accounts = Account.my.order(
|
133
|
+
@accounts = Account.my.order('name')
|
153
134
|
@stage = Setting.unroll(:opportunity_stage)
|
154
135
|
|
155
136
|
respond_with(@lead) do |format|
|
@@ -161,33 +142,26 @@ class LeadsController < EntitiesController
|
|
161
142
|
format.xml { render :xml => @account.errors + @opportunity.errors + @contact.errors, :status => :unprocessable_entity }
|
162
143
|
end
|
163
144
|
end
|
164
|
-
|
165
|
-
rescue ActiveRecord::RecordNotFound
|
166
|
-
respond_to_not_found(:js, :json, :xml)
|
167
145
|
end
|
168
146
|
|
169
147
|
# PUT /leads/1/reject
|
170
148
|
#----------------------------------------------------------------------------
|
171
149
|
def reject
|
172
|
-
@lead
|
173
|
-
@lead.reject if @lead
|
150
|
+
@lead.reject
|
174
151
|
update_sidebar
|
175
152
|
|
176
153
|
respond_with(@lead) do |format|
|
177
154
|
format.html { flash[:notice] = t(:msg_asset_rejected, @lead.full_name); redirect_to leads_path }
|
178
155
|
end
|
179
|
-
|
180
|
-
rescue ActiveRecord::RecordNotFound
|
181
|
-
respond_to_not_found(:html, :js, :json, :xml)
|
182
156
|
end
|
183
157
|
|
184
158
|
# PUT /leads/1/attach
|
185
159
|
#----------------------------------------------------------------------------
|
186
|
-
# Handled by
|
160
|
+
# Handled by EntitiesController :attach
|
187
161
|
|
188
162
|
# POST /leads/1/discard
|
189
163
|
#----------------------------------------------------------------------------
|
190
|
-
# Handled by
|
164
|
+
# Handled by EntitiesController :discard
|
191
165
|
|
192
166
|
# POST /leads/auto_complete/query AJAX
|
193
167
|
#----------------------------------------------------------------------------
|
@@ -229,15 +203,19 @@ class LeadsController < EntitiesController
|
|
229
203
|
# POST /leads/filter AJAX
|
230
204
|
#----------------------------------------------------------------------------
|
231
205
|
def filter
|
232
|
-
session[:
|
206
|
+
session[:leads_filter] = params[:status]
|
233
207
|
@leads = get_leads(:page => 1) # Start one the first page.
|
234
208
|
render :index
|
235
209
|
end
|
236
210
|
|
237
|
-
|
211
|
+
private
|
212
|
+
|
213
|
+
#----------------------------------------------------------------------------
|
214
|
+
alias :get_leads :get_list_of_records
|
215
|
+
|
238
216
|
#----------------------------------------------------------------------------
|
239
|
-
def
|
240
|
-
|
217
|
+
def get_campaigns
|
218
|
+
@campaigns = Campaign.my.order('name')
|
241
219
|
end
|
242
220
|
|
243
221
|
#----------------------------------------------------------------------------
|
@@ -18,7 +18,7 @@
|
|
18
18
|
class OpportunitiesController < EntitiesController
|
19
19
|
before_filter :load_settings
|
20
20
|
before_filter :get_data_for_sidebar, :only => :index
|
21
|
-
before_filter :set_params, :only => [:index, :redraw, :filter]
|
21
|
+
before_filter :set_params, :only => [ :index, :redraw, :filter ]
|
22
22
|
|
23
23
|
# GET /opportunities
|
24
24
|
#----------------------------------------------------------------------------
|
@@ -30,58 +30,51 @@ class OpportunitiesController < EntitiesController
|
|
30
30
|
# GET /opportunities/1
|
31
31
|
#----------------------------------------------------------------------------
|
32
32
|
def show
|
33
|
-
@opportunity = Opportunity.my.find(params[:id])
|
34
|
-
|
35
33
|
respond_with(@opportunity) do |format|
|
36
34
|
format.html do
|
37
35
|
@comment = Comment.new
|
38
36
|
@timeline = timeline(@opportunity)
|
39
37
|
end
|
40
38
|
end
|
41
|
-
|
42
|
-
rescue ActiveRecord::RecordNotFound
|
43
|
-
respond_to_not_found(:html, :json, :xml)
|
44
39
|
end
|
45
40
|
|
46
41
|
# GET /opportunities/new
|
47
42
|
#----------------------------------------------------------------------------
|
48
43
|
def new
|
49
|
-
@opportunity =
|
44
|
+
@opportunity.attributes = {:user => @current_user, :stage => "prospecting", :access => Setting.default_access}
|
50
45
|
@users = User.except(@current_user)
|
51
|
-
@account = Account.new(:user => @current_user)
|
52
|
-
@accounts = Account.my.order(
|
46
|
+
@account = Account.new(:user => @current_user, :access => Setting.default_access)
|
47
|
+
@accounts = Account.my.order('name')
|
48
|
+
|
53
49
|
if params[:related]
|
54
|
-
model, id = params[:related].split(
|
55
|
-
|
50
|
+
model, id = params[:related].split('_')
|
51
|
+
if related = model.classify.constantize.my.find_by_id(id)
|
52
|
+
instance_variable_set("@#{model}", related)
|
53
|
+
else
|
54
|
+
respond_to_related_not_found(model) and return
|
55
|
+
end
|
56
56
|
end
|
57
|
-
respond_with(@opportunity)
|
58
57
|
|
59
|
-
|
60
|
-
respond_to_related_not_found(model, :js) if model
|
58
|
+
respond_with(@opportunity)
|
61
59
|
end
|
62
60
|
|
63
61
|
# GET /opportunities/1/edit AJAX
|
64
62
|
#----------------------------------------------------------------------------
|
65
63
|
def edit
|
66
|
-
@opportunity = Opportunity.my.find(params[:id])
|
67
64
|
@users = User.except(@current_user)
|
68
65
|
@account = @opportunity.account || Account.new(:user => @current_user)
|
69
|
-
@accounts = Account.my.order(
|
66
|
+
@accounts = Account.my.order('name')
|
67
|
+
|
70
68
|
if params[:previous].to_s =~ /(\d+)\z/
|
71
|
-
@previous = Opportunity.my.
|
69
|
+
@previous = Opportunity.my.find_by_id($1) || $1.to_i
|
72
70
|
end
|
73
|
-
respond_with(@opportunity)
|
74
71
|
|
75
|
-
|
76
|
-
@previous ||= $1.to_i
|
77
|
-
respond_to_not_found(:js) unless @opportunity
|
72
|
+
respond_with(@opportunity)
|
78
73
|
end
|
79
74
|
|
80
75
|
# POST /opportunities
|
81
76
|
#----------------------------------------------------------------------------
|
82
77
|
def create
|
83
|
-
@opportunity = Opportunity.new(params[:opportunity])
|
84
|
-
|
85
78
|
respond_with(@opportunity) do |format|
|
86
79
|
if @opportunity.save_with_account_and_permissions(params)
|
87
80
|
if called_from_index_page?
|
@@ -94,7 +87,7 @@ class OpportunitiesController < EntitiesController
|
|
94
87
|
end
|
95
88
|
else
|
96
89
|
@users = User.except(@current_user)
|
97
|
-
@accounts = Account.my.order(
|
90
|
+
@accounts = Account.my.order('name')
|
98
91
|
unless params[:account][:id].blank?
|
99
92
|
@account = Account.find(params[:account][:id])
|
100
93
|
else
|
@@ -113,8 +106,6 @@ class OpportunitiesController < EntitiesController
|
|
113
106
|
# PUT /opportunities/1
|
114
107
|
#----------------------------------------------------------------------------
|
115
108
|
def update
|
116
|
-
@opportunity = Opportunity.my.find(params[:id])
|
117
|
-
|
118
109
|
respond_with(@opportunity) do |format|
|
119
110
|
if @opportunity.update_with_account_and_permissions(params)
|
120
111
|
if called_from_index_page?
|
@@ -126,7 +117,7 @@ class OpportunitiesController < EntitiesController
|
|
126
117
|
end
|
127
118
|
else
|
128
119
|
@users = User.except(@current_user)
|
129
|
-
@accounts = Account.my.order(
|
120
|
+
@accounts = Account.my.order('name')
|
130
121
|
if @opportunity.account
|
131
122
|
@account = Account.find(@opportunity.account.id)
|
132
123
|
else
|
@@ -134,38 +125,31 @@ class OpportunitiesController < EntitiesController
|
|
134
125
|
end
|
135
126
|
end
|
136
127
|
end
|
137
|
-
|
138
|
-
rescue ActiveRecord::RecordNotFound
|
139
|
-
respond_to_not_found(:js, :json, :xml)
|
140
128
|
end
|
141
129
|
|
142
130
|
# DELETE /opportunities/1
|
143
131
|
#----------------------------------------------------------------------------
|
144
132
|
def destroy
|
145
|
-
@opportunity = Opportunity.my.find(params[:id])
|
146
133
|
if called_from_landing_page?(:accounts)
|
147
134
|
@account = @opportunity.account # Reload related account if any.
|
148
135
|
elsif called_from_landing_page?(:campaigns)
|
149
136
|
@campaign = @opportunity.campaign # Reload related campaign if any.
|
150
137
|
end
|
151
|
-
@opportunity.destroy
|
138
|
+
@opportunity.destroy
|
152
139
|
|
153
140
|
respond_with(@opportunity) do |format|
|
154
141
|
format.html { respond_to_destroy(:html) }
|
155
142
|
format.js { respond_to_destroy(:ajax) }
|
156
143
|
end
|
157
|
-
|
158
|
-
rescue ActiveRecord::RecordNotFound
|
159
|
-
respond_to_not_found(:html, :js, :json, :xml)
|
160
144
|
end
|
161
145
|
|
162
146
|
# PUT /opportunities/1/attach
|
163
147
|
#----------------------------------------------------------------------------
|
164
|
-
# Handled by
|
148
|
+
# Handled by EntitiesController :attach
|
165
149
|
|
166
150
|
# POST /opportunities/1/discard
|
167
151
|
#----------------------------------------------------------------------------
|
168
|
-
# Handled by
|
152
|
+
# Handled by EntitiesController :discard
|
169
153
|
|
170
154
|
# POST /opportunities/auto_complete/query AJAX
|
171
155
|
#----------------------------------------------------------------------------
|
@@ -195,11 +179,10 @@ class OpportunitiesController < EntitiesController
|
|
195
179
|
render :index
|
196
180
|
end
|
197
181
|
|
198
|
-
|
182
|
+
private
|
183
|
+
|
199
184
|
#----------------------------------------------------------------------------
|
200
|
-
|
201
|
-
get_list_of_records(Opportunity, options.merge!(:filter => :filter_by_opportunity_stage))
|
202
|
-
end
|
185
|
+
alias :get_opportunities :get_list_of_records
|
203
186
|
|
204
187
|
#----------------------------------------------------------------------------
|
205
188
|
def respond_to_destroy(method)
|
@@ -241,10 +224,11 @@ class OpportunitiesController < EntitiesController
|
|
241
224
|
@stage = Setting.unroll(:opportunity_stage)
|
242
225
|
end
|
243
226
|
|
227
|
+
#----------------------------------------------------------------------------
|
244
228
|
def set_params
|
245
229
|
@current_user.pref[:opportunities_per_page] = params[:per_page] if params[:per_page]
|
246
230
|
@current_user.pref[:opportunities_outline] = params[:outline] if params[:outline]
|
247
231
|
@current_user.pref[:opportunities_sort_by] = Opportunity::sort_by_map[params[:sort_by]] if params[:sort_by]
|
248
|
-
session[:
|
232
|
+
session[:opportunities_filter] = params[:stage] if params[:stage]
|
249
233
|
end
|
250
234
|
end
|
@@ -18,119 +18,105 @@
|
|
18
18
|
class EntitiesController < ApplicationController
|
19
19
|
before_filter :require_user
|
20
20
|
before_filter :set_current_tab, :only => [ :index, :show ]
|
21
|
-
after_filter :update_recently_viewed, :only => :show
|
22
21
|
|
23
|
-
|
24
|
-
respond_to :js
|
25
|
-
respond_to :json, :xml, :except => :edit
|
26
|
-
respond_to :atom, :csv, :rss, :xls, :only => :index
|
22
|
+
load_and_authorize_resource
|
27
23
|
|
28
|
-
|
24
|
+
after_filter :update_recently_viewed, :only => :show
|
29
25
|
|
30
|
-
|
31
|
-
#----------------------------------------------------------------------------
|
32
|
-
def auto_complete
|
33
|
-
@query = params[:auto_complete_query]
|
34
|
-
@auto_complete = hook(:auto_complete, self, :query => @query, :user => @current_user)
|
35
|
-
if @auto_complete.empty?
|
36
|
-
@auto_complete = klass.my.text_search(@query).limit(10)
|
37
|
-
else
|
38
|
-
@auto_complete = @auto_complete.last
|
39
|
-
end
|
40
|
-
session[:auto_complete] = controller_name.to_sym
|
41
|
-
respond_to do |format|
|
42
|
-
format.any(:js, :html) { render "shared/auto_complete", :layout => nil }
|
43
|
-
format.json { render :json => @auto_complete.inject({}){|h,a| h[a.id] = a.name; h } }
|
44
|
-
end
|
45
|
-
end
|
26
|
+
helper_method :entity, :entities, :search
|
46
27
|
|
47
28
|
# Common attach handler for all core controllers.
|
48
29
|
#----------------------------------------------------------------------------
|
49
30
|
def attach
|
50
|
-
model = klass.my.find(params[:id])
|
51
31
|
@attachment = params[:assets].classify.constantize.find(params[:asset_id])
|
52
|
-
@attached =
|
53
|
-
|
54
|
-
@campaign = model.reload if model.is_a?(Campaign)
|
55
|
-
|
56
|
-
respond_to do |format|
|
57
|
-
format.js { render "shared/attach" }
|
58
|
-
format.json { render :json => model.reload }
|
59
|
-
format.xml { render :xml => model.reload }
|
60
|
-
end
|
32
|
+
@attached = entity.attach!(@attachment)
|
33
|
+
entity.reload
|
61
34
|
|
62
|
-
|
63
|
-
respond_to_not_found(:html, :js, :json, :xml)
|
35
|
+
respond_with(entity)
|
64
36
|
end
|
65
37
|
|
66
38
|
# Common discard handler for all core controllers.
|
67
39
|
#----------------------------------------------------------------------------
|
68
40
|
def discard
|
69
|
-
model = klass.my.find(params[:id])
|
70
41
|
@attachment = params[:attachment].constantize.find(params[:attachment_id])
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
42
|
+
entity.discard!(@attachment)
|
43
|
+
entity.reload
|
44
|
+
|
45
|
+
respond_with(entity)
|
46
|
+
end
|
47
|
+
|
48
|
+
# Common subscribe handler for all core controllers.
|
49
|
+
#----------------------------------------------------------------------------
|
50
|
+
def subscribe
|
51
|
+
entity.subscribed_users += [current_user.id]
|
52
|
+
entity.save
|
53
|
+
|
54
|
+
respond_with(entity) do |format|
|
55
|
+
format.js { render 'subscription_update' }
|
79
56
|
end
|
57
|
+
end
|
80
58
|
|
81
|
-
|
82
|
-
|
59
|
+
# Common unsubscribe handler for all core controllers.
|
60
|
+
#----------------------------------------------------------------------------
|
61
|
+
def unsubscribe
|
62
|
+
entity.subscribed_users -= [current_user.id]
|
63
|
+
entity.save
|
64
|
+
|
65
|
+
respond_with(entity) do |format|
|
66
|
+
format.js { render 'subscription_update' }
|
67
|
+
end
|
83
68
|
end
|
84
69
|
|
85
70
|
# GET /entities/contacts AJAX
|
86
71
|
#----------------------------------------------------------------------------
|
87
72
|
def contacts
|
88
|
-
@entity = klass.my.find(params[:id])
|
89
73
|
end
|
90
74
|
|
91
75
|
# GET /entities/leads AJAX
|
92
76
|
#----------------------------------------------------------------------------
|
93
77
|
def leads
|
94
|
-
@entity = klass.my.find(params[:id])
|
95
78
|
end
|
96
79
|
|
97
80
|
# GET /entities/opportunities AJAX
|
98
81
|
#----------------------------------------------------------------------------
|
99
82
|
def opportunities
|
100
|
-
@entity = klass.my.find(params[:id])
|
101
83
|
end
|
102
84
|
|
103
85
|
# GET /entities/versions AJAX
|
104
86
|
#----------------------------------------------------------------------------
|
105
87
|
def versions
|
106
|
-
@entity = klass.my.find(params[:id])
|
107
88
|
end
|
108
89
|
|
109
|
-
|
110
|
-
|
90
|
+
protected
|
91
|
+
|
92
|
+
#----------------------------------------------------------------------------
|
93
|
+
def entity=(entity)
|
94
|
+
instance_variable_set("@#{controller_name.singularize}", entity)
|
111
95
|
end
|
112
96
|
|
113
|
-
# Controller instance method that responds to /controlled/tagged/tag request.
|
114
|
-
# It stores given tag as current query and redirect to index to display all
|
115
|
-
# records tagged with the tag.
|
116
97
|
#----------------------------------------------------------------------------
|
117
|
-
def
|
118
|
-
|
119
|
-
redirect_to :action => "index"
|
98
|
+
def entity
|
99
|
+
instance_variable_get("@#{controller_name.singularize}")
|
120
100
|
end
|
121
101
|
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
@asset = klass.find_by_id(params[:asset_id]) || klass.new
|
126
|
-
render 'fields/group' and return
|
127
|
-
end
|
128
|
-
end
|
129
|
-
render :text => ''
|
102
|
+
#----------------------------------------------------------------------------
|
103
|
+
def entities=(entities)
|
104
|
+
instance_variable_set("@#{controller_name}", entities)
|
130
105
|
end
|
131
106
|
|
132
|
-
|
107
|
+
#----------------------------------------------------------------------------
|
108
|
+
def entities
|
109
|
+
instance_variable_get("@#{controller_name}") || klass.my
|
110
|
+
end
|
133
111
|
|
112
|
+
private
|
113
|
+
|
114
|
+
#----------------------------------------------------------------------------
|
115
|
+
def get_users
|
116
|
+
@users ||= User.except(current_user)
|
117
|
+
end
|
118
|
+
|
119
|
+
#----------------------------------------------------------------------------
|
134
120
|
def search
|
135
121
|
@search ||= begin
|
136
122
|
search = klass.search(params[:q])
|
@@ -141,46 +127,69 @@ class EntitiesController < ApplicationController
|
|
141
127
|
|
142
128
|
# Get list of records for a given model class.
|
143
129
|
#----------------------------------------------------------------------------
|
144
|
-
def get_list_of_records(
|
145
|
-
items = klass.name.tableize
|
130
|
+
def get_list_of_records(options = {})
|
146
131
|
options[:query] ||= params[:query] if params[:query]
|
147
132
|
self.current_page = options[:page] if options[:page]
|
148
133
|
query, tags = parse_query_and_tags(options[:query]) if options[:query]
|
149
134
|
self.current_query = query
|
150
135
|
|
151
|
-
|
152
|
-
|
153
|
-
:order => current_user.pref[:"#{items}_sort_by"] || klass.sort_by
|
154
|
-
}
|
136
|
+
order = current_user.pref[:"#{controller_name}_sort_by"] || klass.sort_by
|
137
|
+
|
155
138
|
pages = {
|
156
139
|
:page => current_page,
|
157
|
-
:per_page => current_user.pref[:"#{
|
140
|
+
:per_page => current_user.pref[:"#{controller_name}_per_page"]
|
158
141
|
}
|
159
142
|
|
160
|
-
# Call the hook and return its output if any.
|
161
|
-
assets = hook(:"get_#{items}", self, :records => records, :pages => pages)
|
162
|
-
return assets.last unless assets.empty?
|
163
|
-
|
164
143
|
# Use default processing if no hooks are present. Note that comma-delimited
|
165
144
|
# export includes deleted records, and the pagination is enabled only for
|
166
145
|
# plain HTTP, Ajax and XML API requests.
|
167
146
|
wants = request.format
|
168
|
-
filter = session[
|
147
|
+
filter = session[:"#{controller_name}_filter"].to_s.split(',')
|
169
148
|
|
170
|
-
scope =
|
171
|
-
scope = scope.merge(search.result)
|
149
|
+
scope = entities.merge(search.result)
|
172
150
|
scope = scope.state(filter) if filter.present?
|
173
151
|
scope = scope.text_search(query) if query.present?
|
174
152
|
scope = scope.tagged_with(tags, :on => :tags) if tags.present?
|
175
|
-
scope = scope.
|
153
|
+
scope = scope.order(order)
|
176
154
|
scope = scope.paginate(pages) if wants.html? || wants.js? || wants.xml?
|
177
155
|
scope
|
178
156
|
end
|
179
157
|
|
180
158
|
#----------------------------------------------------------------------------
|
181
159
|
def update_recently_viewed
|
182
|
-
|
183
|
-
|
160
|
+
entity.versions.create(:event => :view, :whodunnit => PaperTrail.whodunnit)
|
161
|
+
end
|
162
|
+
|
163
|
+
#----------------------------------------------------------------------------
|
164
|
+
def field_group
|
165
|
+
if @tag = Tag.find_by_name(params[:tag].strip)
|
166
|
+
if @field_group = FieldGroup.find_by_tag_id_and_klass_name(@tag.id, klass.to_s)
|
167
|
+
@asset = klass.find_by_id(params[:asset_id]) || klass.new
|
168
|
+
render 'fields/group' and return
|
169
|
+
end
|
170
|
+
end
|
171
|
+
render :text => ''
|
172
|
+
end
|
173
|
+
|
174
|
+
# Somewhat simplistic parser that extracts query and hash-prefixed tags from
|
175
|
+
# the search string and returns them as two element array, for example:
|
176
|
+
#
|
177
|
+
# "#real Billy Bones #pirate" => [ "Billy Bones", "real, pirate" ]
|
178
|
+
#----------------------------------------------------------------------------
|
179
|
+
def parse_query_and_tags(search_string)
|
180
|
+
query, tags = [], []
|
181
|
+
search_string.scan(/[\w@\-\.#]+/).each do |token|
|
182
|
+
if token.starts_with?("#")
|
183
|
+
tags << token[1 .. -1]
|
184
|
+
else
|
185
|
+
query << token
|
186
|
+
end
|
184
187
|
end
|
188
|
+
[ query.join(" "), tags.join(", ") ]
|
189
|
+
end
|
190
|
+
|
191
|
+
#----------------------------------------------------------------------------
|
192
|
+
def timeline(asset)
|
193
|
+
(asset.comments + asset.emails).sort { |x, y| y.created_at <=> x.created_at }
|
185
194
|
end
|
186
195
|
end
|