fat_free_crm 0.11.0 → 0.11.1
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.
- data/.gitignore +1 -0
- data/.travis.yml +2 -2
- data/Gemfile +15 -2
- data/Gemfile.lock +34 -14
- data/README.md +37 -124
- data/app/assets/javascripts/application.js.erb +1 -1
- data/app/assets/javascripts/crm.js +22 -1
- data/app/assets/javascripts/crm_fields.js +2 -3
- data/app/assets/javascripts/jquery-noconflict.js +17 -0
- data/app/assets/stylesheets/application.css.erb +1 -0
- data/app/assets/stylesheets/common.scss +26 -0
- data/app/assets/stylesheets/ffcrm_chosen.scss +1 -1
- data/app/controllers/admin/application_controller.rb +1 -1
- data/app/controllers/application_controller.rb +0 -8
- data/app/controllers/{accounts_controller.rb → entities/accounts_controller.rb} +1 -13
- data/app/controllers/{campaigns_controller.rb → entities/campaigns_controller.rb} +1 -13
- data/app/controllers/{contacts_controller.rb → entities/contacts_controller.rb} +1 -7
- data/app/controllers/{leads_controller.rb → entities/leads_controller.rb} +1 -1
- data/app/controllers/{opportunities_controller.rb → entities/opportunities_controller.rb} +1 -7
- data/app/controllers/{tasks_controller.rb → entities/tasks_controller.rb} +1 -1
- data/app/controllers/{base_controller.rb → entities_controller.rb} +32 -1
- data/app/controllers/home_controller.rb +9 -9
- data/app/controllers/lists_controller.rb +17 -0
- data/app/helpers/admin/tags_helper.rb +1 -1
- data/app/helpers/application_helper.rb +14 -14
- data/app/helpers/crm_tags_helper.rb +1 -1
- data/app/helpers/home_helper.rb +13 -15
- data/app/helpers/lists_helper.rb +17 -0
- data/app/inputs/date_time_input.rb +17 -0
- data/app/inputs/text_input.rb +17 -1
- data/app/models/{base → entities}/account.rb +0 -1
- data/app/models/{base → entities}/account_contact.rb +0 -0
- data/app/models/{base → entities}/account_opportunity.rb +0 -0
- data/app/models/{base → entities}/campaign.rb +0 -1
- data/app/models/{base → entities}/contact.rb +0 -1
- data/app/models/{base → entities}/contact_opportunity.rb +0 -0
- data/app/models/{base → entities}/lead.rb +0 -1
- data/app/models/{base → entities}/opportunity.rb +0 -1
- data/app/models/{base → entities}/task.rb +5 -6
- data/app/models/list.rb +17 -0
- data/app/models/observers/lead_observer.rb +39 -0
- data/app/models/observers/opportunity_observer.rb +54 -0
- data/app/models/observers/task_observer.rb +41 -0
- data/app/models/polymorphic/address.rb +1 -3
- data/app/models/polymorphic/avatar.rb +0 -5
- data/app/models/polymorphic/comment.rb +2 -11
- data/app/models/polymorphic/email.rb +2 -9
- data/app/models/polymorphic/tag.rb +17 -0
- data/app/models/polymorphic/tagging.rb +17 -0
- data/app/models/users/ability.rb +13 -0
- data/app/models/users/user.rb +1 -4
- data/app/views/accounts/_account.html.haml +10 -6
- data/app/views/accounts/index.html.haml +1 -1
- data/app/views/accounts/show.html.haml +6 -24
- data/app/views/admin/fields/_field.html.haml +6 -6
- data/app/views/admin/tags/_tag.html.haml +2 -2
- data/app/views/admin/tags/index.html.haml +1 -1
- data/app/views/admin/users/_user.html.haml +3 -3
- data/app/views/admin/users/index.html.haml +1 -1
- data/app/views/campaigns/_campaign.html.haml +9 -5
- data/app/views/campaigns/index.html.haml +1 -1
- data/app/views/campaigns/show.html.haml +4 -24
- data/app/views/comments/_comment.html.haml +17 -14
- data/app/views/comments/_edit.html.haml +1 -1
- data/app/views/comments/_new.html.haml +3 -3
- data/app/views/contacts/_contact.html.haml +33 -15
- data/app/views/contacts/_contacts.html.haml +6 -0
- data/app/views/contacts/_sidebar_show.html.haml +1 -1
- data/app/views/contacts/index.html.haml +1 -1
- data/app/views/contacts/show.html.haml +3 -19
- data/app/views/emails/_email.html.haml +24 -21
- data/app/views/{base → entities}/_advanced_search.html.haml +0 -0
- data/app/views/{base → entities}/_condition_fields.html.haml +0 -0
- data/app/views/{base → entities}/_grouping_fields.html.haml +0 -0
- data/app/views/{base → entities}/_sort_fields.html.haml +0 -0
- data/app/views/{base → entities}/advanced_search.js.rjs +0 -0
- data/app/views/entities/contacts.js.rjs +3 -0
- data/app/views/entities/leads.js.rjs +3 -0
- data/app/views/entities/opportunities.js.rjs +3 -0
- data/app/views/entities/versions.js.rjs +3 -0
- data/app/views/home/_activity.html.haml +19 -18
- data/app/views/home/_events_menu.html.haml +8 -0
- data/app/views/home/_options.html.haml +2 -3
- data/app/views/home/index.html.haml +1 -1
- data/app/views/leads/_lead.html.haml +42 -23
- data/app/views/leads/_leads.html.haml +6 -0
- data/app/views/leads/_sidebar_show.html.haml +1 -1
- data/app/views/leads/index.html.haml +1 -1
- data/app/views/leads/show.html.haml +3 -13
- data/app/views/opportunities/_opportunities.html.haml +6 -0
- data/app/views/opportunities/_opportunity.html.haml +23 -11
- data/app/views/opportunities/index.html.haml +1 -1
- data/app/views/opportunities/show.html.haml +4 -18
- data/app/views/shared/_comment.html.haml +3 -3
- data/app/views/shared/_edit_comment.html.haml +1 -1
- data/app/views/shared/_recent.html.haml +4 -4
- data/app/views/shared/_recently.html.haml +3 -3
- data/app/views/shared/_timeline.html.haml +2 -3
- data/app/views/tasks/_assigned.html.haml +4 -4
- data/app/views/tasks/_completed.html.haml +2 -2
- data/app/views/tasks/_pending.html.haml +2 -2
- data/app/views/tasks/_related.html.haml +4 -5
- data/app/views/tasks/_tasks.html.haml +3 -0
- data/app/views/tasks/_title.html.haml +1 -1
- data/app/views/tasks/index.html.haml +1 -1
- data/app/views/users/_avatar.html.haml +2 -2
- data/app/views/versions/_version.html.haml +9 -12
- data/app/views/versions/_versions.html.haml +11 -0
- data/config/application.rb +3 -2
- data/config/environments/development.rb +2 -2
- data/config/environments/production.rb +0 -4
- data/config/environments/staging.rb +1 -1
- data/config/initializers/action_mailer.rb +9 -0
- data/config/initializers/paper_trail.rb +80 -0
- data/config/initializers/relative_url_root.rb +23 -0
- data/config/locales/cz_fat_free_crm.yml +1 -1
- data/config/locales/en-US_fat_free_crm.yml +22 -17
- data/config/locales/fr_fat_free_crm.yml +349 -134
- data/config/routes.rb +144 -140
- data/config/settings.default.yml +14 -2
- data/db/demo/addresses.yml +2 -2
- data/db/demo/emails.yml +2 -2
- data/db/migrate/20120216042541_is_paranoid_to_paper_trail.rb +1 -2
- data/db/migrate/20120309070209_add_versions_related.rb +6 -0
- data/db/migrate/20120316045804_activities_to_versions.rb +35 -0
- data/db/schema.rb +79 -53
- data/fat_free_crm.gemspec +8 -4
- data/lib/development_tasks/gem.rake +18 -1
- data/lib/development_tasks/license.rake +2 -4
- data/lib/development_tasks/rdoc.rake +17 -0
- data/lib/development_tasks/rspec.rake +17 -0
- data/lib/fat_free_crm.rb +20 -14
- data/lib/fat_free_crm/core_ext/array.rb +0 -27
- data/lib/fat_free_crm/dropbox.rb +11 -1
- data/lib/fat_free_crm/engine.rb +21 -3
- data/lib/fat_free_crm/gem_dependencies.rb +26 -0
- data/lib/fat_free_crm/gem_ext.rb +18 -1
- data/lib/fat_free_crm/gem_ext/active_record/schema_dumper.rb +18 -1
- data/lib/fat_free_crm/gem_ext/authlogic/session/cookies.rb +17 -0
- data/lib/fat_free_crm/gem_ext/rails/engine.rb +17 -0
- data/lib/fat_free_crm/gem_ext/rails/text_helper.rb +17 -0
- data/lib/fat_free_crm/gem_ext/rake/task.rb +17 -0
- data/lib/fat_free_crm/gem_ext/simple_form/action_view_extensions/form_helper.rb +18 -1
- data/lib/fat_free_crm/plugin_dependencies.rb +23 -5
- data/lib/fat_free_crm/renderers.rb +17 -0
- data/lib/fat_free_crm/syck_yaml.rb +17 -0
- data/lib/fat_free_crm/version.rb +1 -1
- data/lib/{country_select → plugins/country_select}/MIT-LICENSE +0 -0
- data/lib/{country_select → plugins/country_select}/README +0 -0
- data/lib/{country_select → plugins/country_select}/init.rb +0 -0
- data/lib/{country_select → plugins/country_select}/install.rb +0 -0
- data/lib/{country_select → plugins/country_select}/lib/country_select.rb +0 -0
- data/lib/{country_select → plugins/country_select}/uninstall.rb +0 -0
- data/lib/{gravatar_image_tag → plugins/gravatar_image_tag}/Gemfile +0 -0
- data/lib/{gravatar_image_tag → plugins/gravatar_image_tag}/README.textile +0 -0
- data/lib/{gravatar_image_tag → plugins/gravatar_image_tag}/ROADMAP.textile +0 -0
- data/lib/{gravatar_image_tag → plugins/gravatar_image_tag}/Rakefile +0 -0
- data/lib/{gravatar_image_tag → plugins/gravatar_image_tag}/VERSION +0 -0
- data/lib/{gravatar_image_tag → plugins/gravatar_image_tag}/gravatar_image_tag.gemspec +0 -0
- data/lib/{gravatar_image_tag → plugins/gravatar_image_tag}/init.rb +0 -0
- data/lib/{gravatar_image_tag → plugins/gravatar_image_tag}/lib/gravatar_image_tag.rb +0 -0
- data/lib/{gravatar_image_tag → plugins/gravatar_image_tag}/spec/gravatar_image_tag_spec.rb +0 -0
- data/lib/{gravatar_image_tag → plugins/gravatar_image_tag}/spec/test_helper.rb +0 -0
- data/lib/tasks/demo.rake +32 -29
- data/lib/tasks/dropbox.rake +1 -1
- data/lib/tasks/fat_free_crm.rake +3 -2
- data/lib/tasks/plugins.rake +1 -0
- data/spec/controllers/accounts_controller_spec.rb +7 -5
- data/spec/controllers/campaigns_controller_spec.rb +11 -9
- data/spec/controllers/contacts_controller_spec.rb +7 -5
- data/spec/controllers/home_controller_spec.rb +2 -2
- data/spec/controllers/leads_controller_spec.rb +7 -5
- data/spec/controllers/opportunities_controller_spec.rb +7 -5
- data/spec/factories/shared_factories.rb +8 -11
- data/spec/lib/dropbox_spec.rb +1 -0
- data/spec/models/polymorphic/version_spec.rb +247 -0
- data/spec/models/users/user_spec.rb +0 -9
- data/spec/spec_helper.rb +4 -0
- data/spec/views/home/index.haml_spec.rb +1 -1
- data/spec/views/home/index.rjs_spec.rb +4 -4
- data/spec/views/tasks/new.rjs_spec.rb +2 -2
- data/vendor/assets/javascripts/calendar_date_select/format_french.js +24 -0
- metadata +167 -126
- data/app/models/observers/activity_observer.rb +0 -84
- data/app/models/polymorphic/activity.rb +0 -106
- data/app/views/accounts/contacts.js.rjs +0 -3
- data/app/views/accounts/opportunities.js.rjs +0 -3
- data/app/views/campaigns/leads.js.rjs +0 -3
- data/app/views/campaigns/opportunities.js.rjs +0 -3
- data/app/views/contacts/opportunities.js.rjs +0 -3
- data/app/views/home/_actions_menu.html.haml +0 -8
- data/lib/dynamic_form/MIT-LICENSE +0 -20
- data/lib/dynamic_form/README +0 -13
- data/lib/dynamic_form/Rakefile +0 -10
- data/lib/dynamic_form/dynamic_form.gemspec +0 -12
- data/lib/dynamic_form/init.rb +0 -2
- data/lib/dynamic_form/lib/action_view/helpers/dynamic_form.rb +0 -301
- data/lib/dynamic_form/lib/action_view/locale/en-US.yml +0 -8
- data/lib/dynamic_form/lib/dynamic_form.rb +0 -6
- data/lib/dynamic_form/test/dynamic_form_i18n_test.rb +0 -42
- data/lib/dynamic_form/test/dynamic_form_test.rb +0 -370
- data/lib/dynamic_form/test/test_helper.rb +0 -10
- data/lib/responds_to_parent/MIT-LICENSE +0 -20
- data/lib/responds_to_parent/README +0 -47
- data/lib/responds_to_parent/Rakefile +0 -22
- data/lib/responds_to_parent/init.rb +0 -2
- data/lib/responds_to_parent/install.rb +0 -2
- data/lib/responds_to_parent/lib/responds_to_parent.rb +0 -70
- data/lib/responds_to_parent/test/responds_to_parent_test.rb +0 -11
- data/lib/responds_to_parent/test/test_helper.rb +0 -7
- data/lib/responds_to_parent/uninstall.rb +0 -2
- data/spec/models/polymorphic/activity_spec.rb +0 -303
@@ -1,3 +1,20 @@
|
|
1
|
+
# Fat Free CRM
|
2
|
+
# Copyright (C) 2008-2011 by Michael Dvorkin
|
3
|
+
#
|
4
|
+
# This program is free software: you can redistribute it and/or modify
|
5
|
+
# it under the terms of the GNU Affero General Public License as published by
|
6
|
+
# the Free Software Foundation, either version 3 of the License, or
|
7
|
+
# (at your option) any later version.
|
8
|
+
#
|
9
|
+
# This program is distributed in the hope that it will be useful,
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
+
# GNU Affero General Public License for more details.
|
13
|
+
#
|
14
|
+
# You should have received a copy of the GNU Affero General Public License
|
15
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
16
|
+
#------------------------------------------------------------------------------
|
17
|
+
|
1
18
|
class DateTimeInput < SimpleForm::Inputs::DateTimeInput
|
2
19
|
include ActionView::Helpers::TagHelper
|
3
20
|
include ActionView::Helpers::JavaScriptHelper
|
data/app/inputs/text_input.rb
CHANGED
@@ -1,6 +1,22 @@
|
|
1
|
+
# Fat Free CRM
|
2
|
+
# Copyright (C) 2008-2011 by Michael Dvorkin
|
3
|
+
#
|
4
|
+
# This program is free software: you can redistribute it and/or modify
|
5
|
+
# it under the terms of the GNU Affero General Public License as published by
|
6
|
+
# the Free Software Foundation, either version 3 of the License, or
|
7
|
+
# (at your option) any later version.
|
8
|
+
#
|
9
|
+
# This program is distributed in the hope that it will be useful,
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
+
# GNU Affero General Public License for more details.
|
13
|
+
#
|
14
|
+
# You should have received a copy of the GNU Affero General Public License
|
15
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
16
|
+
#------------------------------------------------------------------------------
|
17
|
+
|
1
18
|
class TextInput < SimpleForm::Inputs::TextInput
|
2
19
|
def input
|
3
|
-
add_maxlength!
|
4
20
|
@builder.text_area(attribute_name, {:rows => 7}.merge(input_html_options))
|
5
21
|
end
|
6
22
|
end
|
@@ -45,7 +45,6 @@ class Account < ActiveRecord::Base
|
|
45
45
|
has_many :account_opportunities, :dependent => :destroy
|
46
46
|
has_many :opportunities, :through => :account_opportunities, :uniq => true, :order => "opportunities.id DESC"
|
47
47
|
has_many :tasks, :as => :asset, :dependent => :destroy#, :order => 'created_at DESC'
|
48
|
-
has_many :activities, :as => :subject#, :order => 'created_at DESC'
|
49
48
|
has_one :billing_address, :dependent => :destroy, :as => :addressable, :class_name => "Address", :conditions => "address_type = 'Billing'"
|
50
49
|
has_one :shipping_address, :dependent => :destroy, :as => :addressable, :class_name => "Address", :conditions => "address_type = 'Shipping'"
|
51
50
|
has_many :emails, :as => :mediator
|
File without changes
|
File without changes
|
@@ -47,7 +47,6 @@ class Campaign < ActiveRecord::Base
|
|
47
47
|
has_many :tasks, :as => :asset, :dependent => :destroy#, :order => 'created_at DESC'
|
48
48
|
has_many :leads, :dependent => :destroy, :order => "id DESC"
|
49
49
|
has_many :opportunities, :dependent => :destroy, :order => "id DESC"
|
50
|
-
has_many :activities, :as => :subject#, :order => 'created_at DESC'
|
51
50
|
has_many :emails, :as => :mediator
|
52
51
|
|
53
52
|
scope :state, lambda { |filters|
|
@@ -57,7 +57,6 @@ class Contact < ActiveRecord::Base
|
|
57
57
|
has_many :contact_opportunities, :dependent => :destroy
|
58
58
|
has_many :opportunities, :through => :contact_opportunities, :uniq => true, :order => "opportunities.id DESC"
|
59
59
|
has_many :tasks, :as => :asset, :dependent => :destroy#, :order => 'created_at DESC'
|
60
|
-
has_many :activities, :as => :subject#, :order => 'created_at DESC'
|
61
60
|
has_one :business_address, :dependent => :destroy, :as => :addressable, :class_name => "Address", :conditions => "address_type = 'Business'"
|
62
61
|
has_many :emails, :as => :mediator
|
63
62
|
|
File without changes
|
@@ -54,7 +54,6 @@ class Lead < ActiveRecord::Base
|
|
54
54
|
belongs_to :assignee, :class_name => "User", :foreign_key => :assigned_to
|
55
55
|
has_one :contact, :dependent => :nullify # On destroy keep the contact, but nullify its lead_id
|
56
56
|
has_many :tasks, :as => :asset, :dependent => :destroy#, :order => 'created_at DESC'
|
57
|
-
has_many :activities, :as => :subject#, :order => 'created_at DESC'
|
58
57
|
has_one :business_address, :dependent => :destroy, :as => :addressable, :class_name => "Address", :conditions => "address_type='Business'"
|
59
58
|
has_many :emails, :as => :mediator
|
60
59
|
|
@@ -46,7 +46,6 @@ class Opportunity < ActiveRecord::Base
|
|
46
46
|
has_many :contact_opportunities, :dependent => :destroy
|
47
47
|
has_many :contacts, :through => :contact_opportunities, :uniq => true, :order => "contacts.id DESC"
|
48
48
|
has_many :tasks, :as => :asset, :dependent => :destroy#, :order => 'created_at DESC'
|
49
|
-
has_many :activities, :as => :subject#, :order => 'created_at DESC'
|
50
49
|
has_many :emails, :as => :mediator
|
51
50
|
|
52
51
|
scope :state, lambda { |filters|
|
@@ -40,11 +40,10 @@
|
|
40
40
|
class Task < ActiveRecord::Base
|
41
41
|
attr_accessor :calendar
|
42
42
|
|
43
|
-
belongs_to
|
44
|
-
belongs_to
|
45
|
-
belongs_to
|
46
|
-
belongs_to
|
47
|
-
has_many :activities, :as => :subject#, :order => 'tasks.created_at DESC'
|
43
|
+
belongs_to :user
|
44
|
+
belongs_to :assignee, :class_name => "User", :foreign_key => :assigned_to
|
45
|
+
belongs_to :completor, :class_name => "User", :foreign_key => :completed_by
|
46
|
+
belongs_to :asset, :polymorphic => true
|
48
47
|
|
49
48
|
# Tasks created by the user for herself, or assigned to her by others. That's
|
50
49
|
# what gets shown on Tasks/Pending and Tasks/Completed pages.
|
@@ -98,7 +97,7 @@ class Task < ActiveRecord::Base
|
|
98
97
|
}
|
99
98
|
|
100
99
|
acts_as_commentable
|
101
|
-
has_paper_trail
|
100
|
+
has_paper_trail :meta => { :related => :asset }
|
102
101
|
has_fields
|
103
102
|
exportable
|
104
103
|
|
data/app/models/list.rb
CHANGED
@@ -1,3 +1,20 @@
|
|
1
|
+
# Fat Free CRM
|
2
|
+
# Copyright (C) 2008-2011 by Michael Dvorkin
|
3
|
+
#
|
4
|
+
# This program is free software: you can redistribute it and/or modify
|
5
|
+
# it under the terms of the GNU Affero General Public License as published by
|
6
|
+
# the Free Software Foundation, either version 3 of the License, or
|
7
|
+
# (at your option) any later version.
|
8
|
+
#
|
9
|
+
# This program is distributed in the hope that it will be useful,
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
+
# GNU Affero General Public License for more details.
|
13
|
+
#
|
14
|
+
# You should have received a copy of the GNU Affero General Public License
|
15
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
16
|
+
#------------------------------------------------------------------------------
|
17
|
+
|
1
18
|
class List < ActiveRecord::Base
|
2
19
|
validates_presence_of :name
|
3
20
|
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# Fat Free CRM
|
2
|
+
# Copyright (C) 2008-2011 by Michael Dvorkin
|
3
|
+
#
|
4
|
+
# This program is free software: you can redistribute it and/or modify
|
5
|
+
# it under the terms of the GNU Affero General Public License as published by
|
6
|
+
# the Free Software Foundation, either version 3 of the License, or
|
7
|
+
# (at your option) any later version.
|
8
|
+
#
|
9
|
+
# This program is distributed in the hope that it will be useful,
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
+
# GNU Affero General Public License for more details.
|
13
|
+
#
|
14
|
+
# You should have received a copy of the GNU Affero General Public License
|
15
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
16
|
+
#------------------------------------------------------------------------------
|
17
|
+
|
18
|
+
class LeadObserver < ActiveRecord::Observer
|
19
|
+
observe :lead
|
20
|
+
|
21
|
+
@@leads = {}
|
22
|
+
|
23
|
+
def before_update(item)
|
24
|
+
@@leads[item.id] = Lead.find(item.id).freeze
|
25
|
+
end
|
26
|
+
|
27
|
+
def after_update(item)
|
28
|
+
original = @@leads.delete(item.id)
|
29
|
+
if original && original.status != "rejected" && item.status == "rejected"
|
30
|
+
return log_activity(item, :reject)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def log_activity(item, event)
|
37
|
+
item.send(item.class.versions_association_name).create(:event => event, :whodunnit => PaperTrail.whodunnit)
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# Fat Free CRM
|
2
|
+
# Copyright (C) 2008-2011 by Michael Dvorkin
|
3
|
+
#
|
4
|
+
# This program is free software: you can redistribute it and/or modify
|
5
|
+
# it under the terms of the GNU Affero General Public License as published by
|
6
|
+
# the Free Software Foundation, either version 3 of the License, or
|
7
|
+
# (at your option) any later version.
|
8
|
+
#
|
9
|
+
# This program is distributed in the hope that it will be useful,
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
+
# GNU Affero General Public License for more details.
|
13
|
+
#
|
14
|
+
# You should have received a copy of the GNU Affero General Public License
|
15
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
16
|
+
#------------------------------------------------------------------------------
|
17
|
+
|
18
|
+
class OpportunityObserver < ActiveRecord::Observer
|
19
|
+
observe :opportunity
|
20
|
+
|
21
|
+
@@opportunities = {}
|
22
|
+
|
23
|
+
def after_create(item)
|
24
|
+
if item.campaign && item.stage == "won"
|
25
|
+
update_campaign_revenue(item.campaign, (item.amount || 0) - (item.discount || 0))
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def before_update(item)
|
30
|
+
@@opportunities[item.id] = Opportunity.find(item.id).freeze
|
31
|
+
end
|
32
|
+
|
33
|
+
def after_update(item)
|
34
|
+
original = @@opportunities.delete(item.id)
|
35
|
+
if original
|
36
|
+
if original.stage != "won" && item.stage == "won" # :other to :won -- add to total campaign revenue.
|
37
|
+
update_campaign_revenue(item.campaign, (item.amount || 0) - (item.discount || 0))
|
38
|
+
return log_activity(item, :won)
|
39
|
+
elsif original.stage == "won" && item.stage != "won" # :won to :other -- substract from total campaign revenue.
|
40
|
+
update_campaign_revenue(original.campaign, -((original.amount || 0) - (original.discount || 0)))
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def log_activity(item, event)
|
48
|
+
item.send(item.class.versions_association_name).create(:event => event, :whodunnit => PaperTrail.whodunnit)
|
49
|
+
end
|
50
|
+
|
51
|
+
def update_campaign_revenue(campaign, revenue)
|
52
|
+
campaign.update_attribute(:revenue, (campaign.revenue || 0) + revenue) if campaign
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# Fat Free CRM
|
2
|
+
# Copyright (C) 2008-2011 by Michael Dvorkin
|
3
|
+
#
|
4
|
+
# This program is free software: you can redistribute it and/or modify
|
5
|
+
# it under the terms of the GNU Affero General Public License as published by
|
6
|
+
# the Free Software Foundation, either version 3 of the License, or
|
7
|
+
# (at your option) any later version.
|
8
|
+
#
|
9
|
+
# This program is distributed in the hope that it will be useful,
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
+
# GNU Affero General Public License for more details.
|
13
|
+
#
|
14
|
+
# You should have received a copy of the GNU Affero General Public License
|
15
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
16
|
+
#------------------------------------------------------------------------------
|
17
|
+
|
18
|
+
class TaskObserver < ActiveRecord::Observer
|
19
|
+
observe :task
|
20
|
+
|
21
|
+
@@tasks = {}
|
22
|
+
|
23
|
+
def before_update(item)
|
24
|
+
@@tasks[item.id] = Task.find(item.id).freeze
|
25
|
+
end
|
26
|
+
|
27
|
+
def after_update(item)
|
28
|
+
original = @@tasks.delete(item.id)
|
29
|
+
if original
|
30
|
+
return log_activity(item, :complete) if item.completed_at && original.completed_at.nil?
|
31
|
+
return log_activity(item, :reassign) if item.assigned_to != original.assigned_to
|
32
|
+
return log_activity(item, :reschedule) if item.bucket != original.bucket
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def log_activity(item, event)
|
39
|
+
item.send(item.class.versions_association_name).create(:event => event, :whodunnit => PaperTrail.whodunnit)
|
40
|
+
end
|
41
|
+
end
|
@@ -38,7 +38,7 @@
|
|
38
38
|
class Address < ActiveRecord::Base
|
39
39
|
belongs_to :addressable, :polymorphic => true
|
40
40
|
|
41
|
-
has_paper_trail
|
41
|
+
has_paper_trail :meta => { :related => :addressable }
|
42
42
|
|
43
43
|
scope :business, :conditions => "address_type='Business'"
|
44
44
|
scope :billing, :conditions => "address_type='Billing'"
|
@@ -53,6 +53,4 @@ class Address < ActiveRecord::Base
|
|
53
53
|
self.full_address.blank?
|
54
54
|
end
|
55
55
|
end
|
56
|
-
|
57
56
|
end
|
58
|
-
|
@@ -49,10 +49,5 @@ class Avatar < ActiveRecord::Base
|
|
49
49
|
end
|
50
50
|
has_attached_file :image, :styles => STYLES.dup, :url => "/avatars/:entity_type/:id/:style_:filename", :default_url => "/assets/avatar.jpg"
|
51
51
|
|
52
|
-
# Invert STYLES hash removing trailing #.
|
53
|
-
#----------------------------------------------------------------------------
|
54
|
-
def self.styles
|
55
|
-
Hash[STYLES.map{ |key, value| [ value[0..-2], key ] }]
|
56
|
-
end
|
57
52
|
end
|
58
53
|
|
@@ -34,22 +34,13 @@
|
|
34
34
|
class Comment < ActiveRecord::Base
|
35
35
|
belongs_to :user
|
36
36
|
belongs_to :commentable, :polymorphic => true
|
37
|
-
has_many :activities, :as => :subject#, :order => 'created_at DESC'
|
38
37
|
|
39
|
-
#~ default_scope order('created_at DESC')
|
40
38
|
scope :created_by, lambda { |user| where(:user_id => user.id) }
|
41
39
|
|
42
40
|
validates_presence_of :user, :commentable, :comment
|
43
|
-
|
41
|
+
has_paper_trail :meta => { :related => :commentable },
|
42
|
+
:ignore => [:state]
|
44
43
|
|
45
44
|
def expanded?; self.state == "Expanded"; end
|
46
45
|
def collapsed?; self.state == "Collapsed"; end
|
47
|
-
|
48
|
-
private
|
49
|
-
def log_activity
|
50
|
-
current_user = User.find(user_id)
|
51
|
-
Activity.log(current_user, commentable, :commented) if current_user
|
52
|
-
end
|
53
|
-
|
54
46
|
end
|
55
|
-
|
@@ -43,8 +43,8 @@ class Email < ActiveRecord::Base
|
|
43
43
|
belongs_to :mediator, :polymorphic => true
|
44
44
|
belongs_to :user
|
45
45
|
|
46
|
-
has_paper_trail
|
47
|
-
|
46
|
+
has_paper_trail :meta => { :related => :mediator },
|
47
|
+
:ignore => [:state]
|
48
48
|
|
49
49
|
def expanded?; self.state == "Expanded"; end
|
50
50
|
def collapsed?; self.state == "Collapsed"; end
|
@@ -59,11 +59,4 @@ class Email < ActiveRecord::Base
|
|
59
59
|
end
|
60
60
|
end
|
61
61
|
alias_method_chain :body, :textile
|
62
|
-
|
63
|
-
private
|
64
|
-
def log_activity
|
65
|
-
current_user = User.find(user_id)
|
66
|
-
Activity.log(current_user, mediator, :email) if current_user
|
67
|
-
end
|
68
62
|
end
|
69
|
-
|
@@ -1,3 +1,20 @@
|
|
1
|
+
# Fat Free CRM
|
2
|
+
# Copyright (C) 2008-2011 by Michael Dvorkin
|
3
|
+
#
|
4
|
+
# This program is free software: you can redistribute it and/or modify
|
5
|
+
# it under the terms of the GNU Affero General Public License as published by
|
6
|
+
# the Free Software Foundation, either version 3 of the License, or
|
7
|
+
# (at your option) any later version.
|
8
|
+
#
|
9
|
+
# This program is distributed in the hope that it will be useful,
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
+
# GNU Affero General Public License for more details.
|
13
|
+
#
|
14
|
+
# You should have received a copy of the GNU Affero General Public License
|
15
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
16
|
+
#------------------------------------------------------------------------------
|
17
|
+
|
1
18
|
class Tag < ActsAsTaggableOn::Tag
|
2
19
|
before_destroy :no_associated_field_groups
|
3
20
|
|
@@ -1,2 +1,19 @@
|
|
1
|
+
# Fat Free CRM
|
2
|
+
# Copyright (C) 2008-2011 by Michael Dvorkin
|
3
|
+
#
|
4
|
+
# This program is free software: you can redistribute it and/or modify
|
5
|
+
# it under the terms of the GNU Affero General Public License as published by
|
6
|
+
# the Free Software Foundation, either version 3 of the License, or
|
7
|
+
# (at your option) any later version.
|
8
|
+
#
|
9
|
+
# This program is distributed in the hope that it will be useful,
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
+
# GNU Affero General Public License for more details.
|
13
|
+
#
|
14
|
+
# You should have received a copy of the GNU Affero General Public License
|
15
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
16
|
+
#------------------------------------------------------------------------------
|
17
|
+
|
1
18
|
class Tagging < ActsAsTaggableOn::Tagging
|
2
19
|
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class Ability
|
2
|
+
include CanCan::Ability
|
3
|
+
|
4
|
+
def initialize(user)
|
5
|
+
# See the wiki for details: https://github.com/ryanb/cancan/wiki/Defining-Abilities
|
6
|
+
can :create, :all
|
7
|
+
can [:read, :update, :destroy], :all, :access => 'Public'
|
8
|
+
if user.present?
|
9
|
+
can [:read, :update, :destroy], :all, :user_id => user.id
|
10
|
+
can [:read, :update, :destroy], :all, :permissions => {:user_id => user.id}
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
data/app/models/users/user.rb
CHANGED
@@ -65,7 +65,6 @@ class User < ActiveRecord::Base
|
|
65
65
|
has_many :leads
|
66
66
|
has_many :contacts
|
67
67
|
has_many :opportunities
|
68
|
-
has_many :activities, :dependent => :destroy
|
69
68
|
has_many :permissions, :dependent => :destroy
|
70
69
|
has_many :preferences, :dependent => :destroy
|
71
70
|
|
@@ -96,7 +95,7 @@ class User < ActiveRecord::Base
|
|
96
95
|
# observer without extra authentication query.
|
97
96
|
cattr_accessor :current_user
|
98
97
|
|
99
|
-
validates_presence_of :email,
|
98
|
+
validates_presence_of :email, :message => :missing_email
|
100
99
|
|
101
100
|
#----------------------------------------------------------------------------
|
102
101
|
def name
|
@@ -166,6 +165,4 @@ class User < ActiveRecord::Base
|
|
166
165
|
end
|
167
166
|
artifacts == 0
|
168
167
|
end
|
169
|
-
|
170
168
|
end
|
171
|
-
|
@@ -1,23 +1,27 @@
|
|
1
1
|
- amount = account.opportunities.pipeline.map(&:weighted_amount).sum
|
2
|
-
%li[account]
|
2
|
+
%li.highlight[account]
|
3
3
|
- if account.category
|
4
4
|
.strip{:class => account.category} #{t(account.category)}
|
5
5
|
- else
|
6
6
|
.strip{:style => "color: gray;"} #{t :other}
|
7
7
|
|
8
|
-
.tools
|
8
|
+
%ul.tools
|
9
9
|
= hook(:account_tools_before, self, :account => account)
|
10
|
-
|
11
|
-
|
10
|
+
|
11
|
+
- if can?(:update, account)
|
12
|
+
%li= link_to_edit(account)
|
13
|
+
|
14
|
+
- if can?(:destroy, account)
|
15
|
+
%li= link_to_delete(account)
|
12
16
|
|
13
17
|
.indent
|
14
|
-
= link_to(
|
18
|
+
= link_to(account.name, account)
|
15
19
|
- if amount != 0.0
|
16
20
|
%span.amount= number_to_currency(amount, :precision => 0)
|
17
21
|
–
|
18
22
|
%tt
|
19
23
|
= account.location << ", " unless account.location.blank?
|
20
|
-
= t(:added_by, :time_ago => time_ago_in_words(account.created_at), :user => (account.user.id == @current_user.id ? t(:me) :
|
24
|
+
= t(:added_by, :time_ago => time_ago_in_words(account.created_at), :user => (account.user.id == @current_user.id ? t(:me) : account.user.full_name)) << " | "
|
21
25
|
= t('pluralize.contact', account.contacts.count) << " | "
|
22
26
|
= t('pluralize.opportunity', account.opportunities.count)
|
23
27
|
|