fat_free_crm 0.11.0 → 0.11.1

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.

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