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.

Files changed (212) hide show
  1. data/.gitignore +1 -0
  2. data/.travis.yml +2 -2
  3. data/Gemfile +15 -2
  4. data/Gemfile.lock +34 -14
  5. data/README.md +37 -124
  6. data/app/assets/javascripts/application.js.erb +1 -1
  7. data/app/assets/javascripts/crm.js +22 -1
  8. data/app/assets/javascripts/crm_fields.js +2 -3
  9. data/app/assets/javascripts/jquery-noconflict.js +17 -0
  10. data/app/assets/stylesheets/application.css.erb +1 -0
  11. data/app/assets/stylesheets/common.scss +26 -0
  12. data/app/assets/stylesheets/ffcrm_chosen.scss +1 -1
  13. data/app/controllers/admin/application_controller.rb +1 -1
  14. data/app/controllers/application_controller.rb +0 -8
  15. data/app/controllers/{accounts_controller.rb → entities/accounts_controller.rb} +1 -13
  16. data/app/controllers/{campaigns_controller.rb → entities/campaigns_controller.rb} +1 -13
  17. data/app/controllers/{contacts_controller.rb → entities/contacts_controller.rb} +1 -7
  18. data/app/controllers/{leads_controller.rb → entities/leads_controller.rb} +1 -1
  19. data/app/controllers/{opportunities_controller.rb → entities/opportunities_controller.rb} +1 -7
  20. data/app/controllers/{tasks_controller.rb → entities/tasks_controller.rb} +1 -1
  21. data/app/controllers/{base_controller.rb → entities_controller.rb} +32 -1
  22. data/app/controllers/home_controller.rb +9 -9
  23. data/app/controllers/lists_controller.rb +17 -0
  24. data/app/helpers/admin/tags_helper.rb +1 -1
  25. data/app/helpers/application_helper.rb +14 -14
  26. data/app/helpers/crm_tags_helper.rb +1 -1
  27. data/app/helpers/home_helper.rb +13 -15
  28. data/app/helpers/lists_helper.rb +17 -0
  29. data/app/inputs/date_time_input.rb +17 -0
  30. data/app/inputs/text_input.rb +17 -1
  31. data/app/models/{base → entities}/account.rb +0 -1
  32. data/app/models/{base → entities}/account_contact.rb +0 -0
  33. data/app/models/{base → entities}/account_opportunity.rb +0 -0
  34. data/app/models/{base → entities}/campaign.rb +0 -1
  35. data/app/models/{base → entities}/contact.rb +0 -1
  36. data/app/models/{base → entities}/contact_opportunity.rb +0 -0
  37. data/app/models/{base → entities}/lead.rb +0 -1
  38. data/app/models/{base → entities}/opportunity.rb +0 -1
  39. data/app/models/{base → entities}/task.rb +5 -6
  40. data/app/models/list.rb +17 -0
  41. data/app/models/observers/lead_observer.rb +39 -0
  42. data/app/models/observers/opportunity_observer.rb +54 -0
  43. data/app/models/observers/task_observer.rb +41 -0
  44. data/app/models/polymorphic/address.rb +1 -3
  45. data/app/models/polymorphic/avatar.rb +0 -5
  46. data/app/models/polymorphic/comment.rb +2 -11
  47. data/app/models/polymorphic/email.rb +2 -9
  48. data/app/models/polymorphic/tag.rb +17 -0
  49. data/app/models/polymorphic/tagging.rb +17 -0
  50. data/app/models/users/ability.rb +13 -0
  51. data/app/models/users/user.rb +1 -4
  52. data/app/views/accounts/_account.html.haml +10 -6
  53. data/app/views/accounts/index.html.haml +1 -1
  54. data/app/views/accounts/show.html.haml +6 -24
  55. data/app/views/admin/fields/_field.html.haml +6 -6
  56. data/app/views/admin/tags/_tag.html.haml +2 -2
  57. data/app/views/admin/tags/index.html.haml +1 -1
  58. data/app/views/admin/users/_user.html.haml +3 -3
  59. data/app/views/admin/users/index.html.haml +1 -1
  60. data/app/views/campaigns/_campaign.html.haml +9 -5
  61. data/app/views/campaigns/index.html.haml +1 -1
  62. data/app/views/campaigns/show.html.haml +4 -24
  63. data/app/views/comments/_comment.html.haml +17 -14
  64. data/app/views/comments/_edit.html.haml +1 -1
  65. data/app/views/comments/_new.html.haml +3 -3
  66. data/app/views/contacts/_contact.html.haml +33 -15
  67. data/app/views/contacts/_contacts.html.haml +6 -0
  68. data/app/views/contacts/_sidebar_show.html.haml +1 -1
  69. data/app/views/contacts/index.html.haml +1 -1
  70. data/app/views/contacts/show.html.haml +3 -19
  71. data/app/views/emails/_email.html.haml +24 -21
  72. data/app/views/{base → entities}/_advanced_search.html.haml +0 -0
  73. data/app/views/{base → entities}/_condition_fields.html.haml +0 -0
  74. data/app/views/{base → entities}/_grouping_fields.html.haml +0 -0
  75. data/app/views/{base → entities}/_sort_fields.html.haml +0 -0
  76. data/app/views/{base → entities}/advanced_search.js.rjs +0 -0
  77. data/app/views/entities/contacts.js.rjs +3 -0
  78. data/app/views/entities/leads.js.rjs +3 -0
  79. data/app/views/entities/opportunities.js.rjs +3 -0
  80. data/app/views/entities/versions.js.rjs +3 -0
  81. data/app/views/home/_activity.html.haml +19 -18
  82. data/app/views/home/_events_menu.html.haml +8 -0
  83. data/app/views/home/_options.html.haml +2 -3
  84. data/app/views/home/index.html.haml +1 -1
  85. data/app/views/leads/_lead.html.haml +42 -23
  86. data/app/views/leads/_leads.html.haml +6 -0
  87. data/app/views/leads/_sidebar_show.html.haml +1 -1
  88. data/app/views/leads/index.html.haml +1 -1
  89. data/app/views/leads/show.html.haml +3 -13
  90. data/app/views/opportunities/_opportunities.html.haml +6 -0
  91. data/app/views/opportunities/_opportunity.html.haml +23 -11
  92. data/app/views/opportunities/index.html.haml +1 -1
  93. data/app/views/opportunities/show.html.haml +4 -18
  94. data/app/views/shared/_comment.html.haml +3 -3
  95. data/app/views/shared/_edit_comment.html.haml +1 -1
  96. data/app/views/shared/_recent.html.haml +4 -4
  97. data/app/views/shared/_recently.html.haml +3 -3
  98. data/app/views/shared/_timeline.html.haml +2 -3
  99. data/app/views/tasks/_assigned.html.haml +4 -4
  100. data/app/views/tasks/_completed.html.haml +2 -2
  101. data/app/views/tasks/_pending.html.haml +2 -2
  102. data/app/views/tasks/_related.html.haml +4 -5
  103. data/app/views/tasks/_tasks.html.haml +3 -0
  104. data/app/views/tasks/_title.html.haml +1 -1
  105. data/app/views/tasks/index.html.haml +1 -1
  106. data/app/views/users/_avatar.html.haml +2 -2
  107. data/app/views/versions/_version.html.haml +9 -12
  108. data/app/views/versions/_versions.html.haml +11 -0
  109. data/config/application.rb +3 -2
  110. data/config/environments/development.rb +2 -2
  111. data/config/environments/production.rb +0 -4
  112. data/config/environments/staging.rb +1 -1
  113. data/config/initializers/action_mailer.rb +9 -0
  114. data/config/initializers/paper_trail.rb +80 -0
  115. data/config/initializers/relative_url_root.rb +23 -0
  116. data/config/locales/cz_fat_free_crm.yml +1 -1
  117. data/config/locales/en-US_fat_free_crm.yml +22 -17
  118. data/config/locales/fr_fat_free_crm.yml +349 -134
  119. data/config/routes.rb +144 -140
  120. data/config/settings.default.yml +14 -2
  121. data/db/demo/addresses.yml +2 -2
  122. data/db/demo/emails.yml +2 -2
  123. data/db/migrate/20120216042541_is_paranoid_to_paper_trail.rb +1 -2
  124. data/db/migrate/20120309070209_add_versions_related.rb +6 -0
  125. data/db/migrate/20120316045804_activities_to_versions.rb +35 -0
  126. data/db/schema.rb +79 -53
  127. data/fat_free_crm.gemspec +8 -4
  128. data/lib/development_tasks/gem.rake +18 -1
  129. data/lib/development_tasks/license.rake +2 -4
  130. data/lib/development_tasks/rdoc.rake +17 -0
  131. data/lib/development_tasks/rspec.rake +17 -0
  132. data/lib/fat_free_crm.rb +20 -14
  133. data/lib/fat_free_crm/core_ext/array.rb +0 -27
  134. data/lib/fat_free_crm/dropbox.rb +11 -1
  135. data/lib/fat_free_crm/engine.rb +21 -3
  136. data/lib/fat_free_crm/gem_dependencies.rb +26 -0
  137. data/lib/fat_free_crm/gem_ext.rb +18 -1
  138. data/lib/fat_free_crm/gem_ext/active_record/schema_dumper.rb +18 -1
  139. data/lib/fat_free_crm/gem_ext/authlogic/session/cookies.rb +17 -0
  140. data/lib/fat_free_crm/gem_ext/rails/engine.rb +17 -0
  141. data/lib/fat_free_crm/gem_ext/rails/text_helper.rb +17 -0
  142. data/lib/fat_free_crm/gem_ext/rake/task.rb +17 -0
  143. data/lib/fat_free_crm/gem_ext/simple_form/action_view_extensions/form_helper.rb +18 -1
  144. data/lib/fat_free_crm/plugin_dependencies.rb +23 -5
  145. data/lib/fat_free_crm/renderers.rb +17 -0
  146. data/lib/fat_free_crm/syck_yaml.rb +17 -0
  147. data/lib/fat_free_crm/version.rb +1 -1
  148. data/lib/{country_select → plugins/country_select}/MIT-LICENSE +0 -0
  149. data/lib/{country_select → plugins/country_select}/README +0 -0
  150. data/lib/{country_select → plugins/country_select}/init.rb +0 -0
  151. data/lib/{country_select → plugins/country_select}/install.rb +0 -0
  152. data/lib/{country_select → plugins/country_select}/lib/country_select.rb +0 -0
  153. data/lib/{country_select → plugins/country_select}/uninstall.rb +0 -0
  154. data/lib/{gravatar_image_tag → plugins/gravatar_image_tag}/Gemfile +0 -0
  155. data/lib/{gravatar_image_tag → plugins/gravatar_image_tag}/README.textile +0 -0
  156. data/lib/{gravatar_image_tag → plugins/gravatar_image_tag}/ROADMAP.textile +0 -0
  157. data/lib/{gravatar_image_tag → plugins/gravatar_image_tag}/Rakefile +0 -0
  158. data/lib/{gravatar_image_tag → plugins/gravatar_image_tag}/VERSION +0 -0
  159. data/lib/{gravatar_image_tag → plugins/gravatar_image_tag}/gravatar_image_tag.gemspec +0 -0
  160. data/lib/{gravatar_image_tag → plugins/gravatar_image_tag}/init.rb +0 -0
  161. data/lib/{gravatar_image_tag → plugins/gravatar_image_tag}/lib/gravatar_image_tag.rb +0 -0
  162. data/lib/{gravatar_image_tag → plugins/gravatar_image_tag}/spec/gravatar_image_tag_spec.rb +0 -0
  163. data/lib/{gravatar_image_tag → plugins/gravatar_image_tag}/spec/test_helper.rb +0 -0
  164. data/lib/tasks/demo.rake +32 -29
  165. data/lib/tasks/dropbox.rake +1 -1
  166. data/lib/tasks/fat_free_crm.rake +3 -2
  167. data/lib/tasks/plugins.rake +1 -0
  168. data/spec/controllers/accounts_controller_spec.rb +7 -5
  169. data/spec/controllers/campaigns_controller_spec.rb +11 -9
  170. data/spec/controllers/contacts_controller_spec.rb +7 -5
  171. data/spec/controllers/home_controller_spec.rb +2 -2
  172. data/spec/controllers/leads_controller_spec.rb +7 -5
  173. data/spec/controllers/opportunities_controller_spec.rb +7 -5
  174. data/spec/factories/shared_factories.rb +8 -11
  175. data/spec/lib/dropbox_spec.rb +1 -0
  176. data/spec/models/polymorphic/version_spec.rb +247 -0
  177. data/spec/models/users/user_spec.rb +0 -9
  178. data/spec/spec_helper.rb +4 -0
  179. data/spec/views/home/index.haml_spec.rb +1 -1
  180. data/spec/views/home/index.rjs_spec.rb +4 -4
  181. data/spec/views/tasks/new.rjs_spec.rb +2 -2
  182. data/vendor/assets/javascripts/calendar_date_select/format_french.js +24 -0
  183. metadata +167 -126
  184. data/app/models/observers/activity_observer.rb +0 -84
  185. data/app/models/polymorphic/activity.rb +0 -106
  186. data/app/views/accounts/contacts.js.rjs +0 -3
  187. data/app/views/accounts/opportunities.js.rjs +0 -3
  188. data/app/views/campaigns/leads.js.rjs +0 -3
  189. data/app/views/campaigns/opportunities.js.rjs +0 -3
  190. data/app/views/contacts/opportunities.js.rjs +0 -3
  191. data/app/views/home/_actions_menu.html.haml +0 -8
  192. data/lib/dynamic_form/MIT-LICENSE +0 -20
  193. data/lib/dynamic_form/README +0 -13
  194. data/lib/dynamic_form/Rakefile +0 -10
  195. data/lib/dynamic_form/dynamic_form.gemspec +0 -12
  196. data/lib/dynamic_form/init.rb +0 -2
  197. data/lib/dynamic_form/lib/action_view/helpers/dynamic_form.rb +0 -301
  198. data/lib/dynamic_form/lib/action_view/locale/en-US.yml +0 -8
  199. data/lib/dynamic_form/lib/dynamic_form.rb +0 -6
  200. data/lib/dynamic_form/test/dynamic_form_i18n_test.rb +0 -42
  201. data/lib/dynamic_form/test/dynamic_form_test.rb +0 -370
  202. data/lib/dynamic_form/test/test_helper.rb +0 -10
  203. data/lib/responds_to_parent/MIT-LICENSE +0 -20
  204. data/lib/responds_to_parent/README +0 -47
  205. data/lib/responds_to_parent/Rakefile +0 -22
  206. data/lib/responds_to_parent/init.rb +0 -2
  207. data/lib/responds_to_parent/install.rb +0 -2
  208. data/lib/responds_to_parent/lib/responds_to_parent.rb +0 -70
  209. data/lib/responds_to_parent/test/responds_to_parent_test.rb +0 -11
  210. data/lib/responds_to_parent/test/test_helper.rb +0 -7
  211. data/lib/responds_to_parent/uninstall.rb +0 -2
  212. 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
@@ -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
@@ -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
 
@@ -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 :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
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
 
@@ -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
- after_create :log_activity
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
- after_create :log_activity
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
@@ -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, :message => :missing_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]{ highlightable(dom_id(account, :tools)) }
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{ invisible, :id => dom_id(account, :tools) }
8
+ %ul.tools
9
9
  = hook(:account_tools_before, self, :account => account)
10
- = link_to_edit(account) + " | "
11
- = link_to_delete(account)
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(h(account.name), account)
18
+ = link_to(account.name, account)
15
19
  - if amount != 0.0
16
20
  %span.amount= number_to_currency(amount, :precision => 0)
17
21
  &ndash;
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) : h(account.user.full_name))) << " | "
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