fat_free_crm 0.11.1 → 0.11.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of fat_free_crm might be problematic. Click here for more details.

Files changed (179) hide show
  1. data/Gemfile +30 -12
  2. data/Gemfile.lock +131 -119
  3. data/Procfile +1 -1
  4. data/README.md +1 -1
  5. data/app/assets/images/notifications.png +0 -0
  6. data/app/assets/javascripts/application.js.erb +3 -0
  7. data/app/assets/javascripts/crm_textarea_autocomplete.js +44 -0
  8. data/app/assets/stylesheets/application.css.erb +2 -0
  9. data/app/assets/stylesheets/common.scss +7 -11
  10. data/app/assets/stylesheets/textarea_autocomplete.scss +42 -0
  11. data/app/controllers/admin/application_controller.rb +5 -5
  12. data/app/controllers/admin/field_groups_controller.rb +11 -51
  13. data/app/controllers/admin/fields_controller.rb +13 -59
  14. data/app/controllers/admin/plugins_controller.rb +1 -4
  15. data/app/controllers/admin/settings_controller.rb +0 -4
  16. data/app/controllers/admin/tags_controller.rb +11 -66
  17. data/app/controllers/admin/users_controller.rb +20 -83
  18. data/app/controllers/application_controller.rb +83 -69
  19. data/app/controllers/comments_controller.rb +12 -29
  20. data/app/controllers/emails_controller.rb +1 -5
  21. data/app/controllers/entities/accounts_controller.rb +13 -32
  22. data/app/controllers/entities/campaigns_controller.rb +17 -32
  23. data/app/controllers/entities/contacts_controller.rb +20 -38
  24. data/app/controllers/entities/leads_controller.rb +33 -55
  25. data/app/controllers/entities/opportunities_controller.rb +26 -42
  26. data/app/controllers/entities_controller.rb +92 -83
  27. data/app/controllers/home_controller.rb +1 -10
  28. data/app/controllers/lists_controller.rb +1 -4
  29. data/app/controllers/{entities/tasks_controller.rb → tasks_controller.rb} +21 -32
  30. data/app/controllers/users_controller.rb +6 -5
  31. data/app/helpers/accounts_helper.rb +32 -9
  32. data/app/helpers/application_helper.rb +15 -1
  33. data/app/helpers/campaigns_helper.rb +1 -1
  34. data/app/helpers/comments_helper.rb +11 -1
  35. data/app/helpers/leads_helper.rb +1 -1
  36. data/app/helpers/opportunities_helper.rb +1 -1
  37. data/app/{models/mailers/notifier.rb → mailers/dropbox_mailer.rb} +5 -16
  38. data/app/mailers/subscription_mailer.rb +37 -0
  39. data/{lib/tasks/dropbox.rake → app/mailers/user_mailer.rb} +11 -13
  40. data/app/models/entities/account.rb +3 -1
  41. data/app/models/entities/campaign.rb +3 -1
  42. data/app/models/entities/contact.rb +3 -1
  43. data/app/models/entities/lead.rb +6 -5
  44. data/app/models/entities/opportunity.rb +3 -1
  45. data/app/models/fields/field.rb +1 -1
  46. data/app/models/polymorphic/comment.rb +34 -0
  47. data/app/models/{entities → polymorphic}/task.rb +16 -3
  48. data/app/models/setting.rb +15 -15
  49. data/app/models/users/ability.rb +12 -5
  50. data/app/models/users/user.rb +7 -2
  51. data/app/views/accounts/index.html.haml +1 -1
  52. data/app/views/accounts/index.js.rjs +1 -1
  53. data/app/views/admin/plugins/index.html.haml +1 -7
  54. data/app/views/{shared/auto_complete.html.haml → application/_auto_complete.html.haml} +0 -0
  55. data/app/views/{shared → application}/index.atom.builder +1 -1
  56. data/app/views/{shared → application}/index.rss.builder +1 -1
  57. data/app/views/campaigns/index.html.haml +1 -1
  58. data/app/views/campaigns/index.js.rjs +1 -1
  59. data/app/views/comments/_new.html.haml +6 -0
  60. data/app/views/comments/_subscription_links.html.haml +13 -0
  61. data/app/views/comments/new.js.rjs +2 -0
  62. data/app/views/contacts/_top_section.html.haml +3 -13
  63. data/app/views/contacts/index.html.haml +1 -1
  64. data/app/views/contacts/index.js.rjs +1 -1
  65. data/app/views/{notifier/dropbox_ack_notification.html.haml → dropbox_mailer/dropbox_notification.html.haml} +2 -2
  66. data/app/views/{shared → entities}/attach.js.rjs +1 -1
  67. data/app/views/entities/contacts.js.rjs +1 -1
  68. data/app/views/{shared/discard.rjs → entities/discard.js.rjs} +0 -0
  69. data/app/views/entities/leads.js.rjs +1 -1
  70. data/app/views/entities/opportunities.js.rjs +1 -1
  71. data/app/views/entities/subscription_update.js.rjs +4 -0
  72. data/app/views/entities/versions.js.rjs +1 -1
  73. data/app/views/layouts/_footer.html.haml +1 -1
  74. data/app/views/layouts/application.html.haml +3 -0
  75. data/app/views/leads/_contact.html.haml +1 -0
  76. data/app/views/leads/index.html.haml +1 -1
  77. data/app/views/leads/index.js.rjs +1 -1
  78. data/app/views/opportunities/_top_section.html.haml +4 -14
  79. data/app/views/opportunities/index.html.haml +1 -1
  80. data/app/views/opportunities/index.js.rjs +1 -1
  81. data/app/views/subscription_mailer/comment_notification.text.erb +7 -0
  82. data/app/views/{notifier → user_mailer}/password_reset_instructions.html.haml +0 -0
  83. data/config/application.rb +3 -1
  84. data/config/environments/development.rb +1 -1
  85. data/config/environments/test.rb +3 -0
  86. data/config/initializers/action_mailer.rb +8 -5
  87. data/config/initializers/cancan.rb +151 -0
  88. data/config/initializers/constants.rb +1 -0
  89. data/config/initializers/locale.rb +20 -0
  90. data/config/initializers/paper_trail.rb +4 -5
  91. data/config/initializers/relative_url_root.rb +0 -1
  92. data/config/initializers/squeel.rb +5 -0
  93. data/config/locales/cz_fat_free_crm.yml +3 -3
  94. data/config/locales/de.yml +2 -2
  95. data/config/locales/de_fat_free_crm.yml +651 -596
  96. data/config/locales/en-GB_fat_free_crm.yml +3 -3
  97. data/config/locales/en-US_fat_free_crm.yml +13 -3
  98. data/config/locales/es_fat_free_crm.yml +3 -3
  99. data/config/locales/fr-CA_fat_free_crm.yml +3 -3
  100. data/config/locales/fr_fat_free_crm.yml +3 -3
  101. data/config/locales/it_fat_free_crm.yml +3 -3
  102. data/config/locales/pl_fat_free_crm.yml +3 -3
  103. data/config/locales/pt-BR_fat_free_crm.yml +3 -3
  104. data/config/locales/ru_fat_free_crm.yml +3 -3
  105. data/config/locales/sv-SE_fat_free_crm.yml +3 -3
  106. data/config/locales/th_fat_free_crm.yml +3 -3
  107. data/config/routes.rb +10 -0
  108. data/config/settings.default.yml +29 -10
  109. data/config/unicorn.rb +4 -0
  110. data/db/migrate/20111201030535_add_field_groups_klass_name.rb +3 -1
  111. data/db/migrate/20120314080441_add_subscribed_users_to_entities.rb +23 -0
  112. data/db/migrate/20120405080727_change_subscribed_users_to_set.rb +24 -0
  113. data/db/migrate/20120405080742_change_further_subscribed_users_to_set.rb +27 -0
  114. data/db/migrate/20120413034923_add_index_on_versions_item_type.rb +5 -0
  115. data/db/schema.rb +109 -126
  116. data/fat_free_crm.gemspec +12 -18
  117. data/lib/fat_free_crm.rb +0 -1
  118. data/lib/fat_free_crm/core_ext/array.rb +1 -0
  119. data/lib/fat_free_crm/gem_dependencies.rb +1 -0
  120. data/lib/fat_free_crm/mail_processor/base.rb +226 -0
  121. data/lib/fat_free_crm/mail_processor/comment_replies.rb +86 -0
  122. data/lib/fat_free_crm/mail_processor/dropbox.rb +288 -0
  123. data/lib/fat_free_crm/permissions.rb +6 -19
  124. data/lib/fat_free_crm/renderers.rb +0 -8
  125. data/lib/fat_free_crm/tabs.rb +1 -1
  126. data/lib/fat_free_crm/version.rb +1 -1
  127. data/lib/plugins/country_select/lib/country_select.rb +2 -2
  128. data/lib/tasks/mail_processing.rake +60 -0
  129. data/spec/controllers/admin/users_controller_spec.rb +0 -2
  130. data/spec/controllers/{accounts_controller_spec.rb → entities/accounts_controller_spec.rb} +7 -9
  131. data/spec/controllers/{campaigns_controller_spec.rb → entities/campaigns_controller_spec.rb} +7 -7
  132. data/spec/controllers/{contacts_controller_spec.rb → entities/contacts_controller_spec.rb} +5 -9
  133. data/spec/controllers/{leads_controller_spec.rb → entities/leads_controller_spec.rb} +7 -9
  134. data/spec/controllers/{opportunities_controller_spec.rb → entities/opportunities_controller_spec.rb} +8 -15
  135. data/spec/controllers/tasks_controller_spec.rb +1 -5
  136. data/spec/controllers/users_controller_spec.rb +5 -9
  137. data/spec/factories/subscription_factories.rb +6 -0
  138. data/spec/lib/mail_processor/base_spec.rb +164 -0
  139. data/spec/lib/mail_processor/comment_replies_spec.rb +63 -0
  140. data/spec/lib/{dropbox_spec.rb → mail_processor/dropbox_spec.rb} +73 -181
  141. data/spec/lib/mail_processor/sample_emails/dropbox.rb +167 -0
  142. data/spec/mailers/subscription_mailer_spec.rb +17 -0
  143. data/spec/models/{base → entities}/account_contact_spec.rb +0 -0
  144. data/spec/models/{base → entities}/account_opportunity_spec.rb +0 -0
  145. data/spec/models/{base → entities}/account_spec.rb +4 -0
  146. data/spec/models/{base → entities}/campaign_spec.rb +4 -0
  147. data/spec/models/{base → entities}/contact_opportunity_spec.rb +0 -0
  148. data/spec/models/{base → entities}/contact_spec.rb +4 -0
  149. data/spec/models/{base → entities}/lead_spec.rb +4 -0
  150. data/spec/models/{base → entities}/opportunity_spec.rb +4 -0
  151. data/spec/models/polymorphic/comment_spec.rb +15 -0
  152. data/spec/models/{base → polymorphic}/task_spec.rb +124 -30
  153. data/spec/models/polymorphic/version_spec.rb +1 -1
  154. data/spec/shared/controllers.rb +5 -7
  155. data/spec/shared/models.rb +46 -0
  156. data/spec/spec_helper.rb +3 -4
  157. data/spec/support/mail_processor_mocks.rb +30 -0
  158. data/spec/support/uploaded_file.rb +3 -0
  159. data/spec/views/{common → application}/auto_complete.haml_spec.rb +1 -1
  160. data/vendor/assets/images/jquery-ui/ui-bg_diagonals-thick_18_b81900_40x40.png +0 -0
  161. data/vendor/assets/images/jquery-ui/ui-bg_diagonals-thick_20_666666_40x40.png +0 -0
  162. data/vendor/assets/images/jquery-ui/ui-bg_flat_10_000000_40x100.png +0 -0
  163. data/vendor/assets/images/jquery-ui/ui-bg_glass_100_f6f6f6_1x400.png +0 -0
  164. data/vendor/assets/images/jquery-ui/ui-bg_glass_100_fdf5ce_1x400.png +0 -0
  165. data/vendor/assets/images/jquery-ui/ui-bg_glass_65_ffffff_1x400.png +0 -0
  166. data/vendor/assets/images/jquery-ui/ui-bg_gloss-wave_35_f6a828_500x100.png +0 -0
  167. data/vendor/assets/images/jquery-ui/ui-bg_highlight-soft_100_eeeeee_1x100.png +0 -0
  168. data/vendor/assets/images/jquery-ui/ui-bg_highlight-soft_75_ffe45c_1x100.png +0 -0
  169. data/vendor/assets/images/jquery-ui/ui-icons_222222_256x240.png +0 -0
  170. data/vendor/assets/images/jquery-ui/ui-icons_228ef1_256x240.png +0 -0
  171. data/vendor/assets/images/jquery-ui/ui-icons_ef8c08_256x240.png +0 -0
  172. data/vendor/assets/images/jquery-ui/ui-icons_ffd27a_256x240.png +0 -0
  173. data/vendor/assets/images/jquery-ui/ui-icons_ffffff_256x240.png +0 -0
  174. data/vendor/assets/javascripts/textarea_autocomplete.js +605 -0
  175. data/vendor/assets/stylesheets/jquery-ui.custom.css.erb +565 -0
  176. metadata +234 -154
  177. data/config/locales/simple_form.en.yml +0 -24
  178. data/lib/fat_free_crm/dropbox.rb +0 -439
  179. data/spec/lib/dropbox/email_samples.rb +0 -77
@@ -10,3 +10,5 @@ else
10
10
  page["#{id_prefix}_ask"].show
11
11
  end
12
12
 
13
+
14
+ page.call "crm.textarea_user_autocomplete", "#{id_prefix}_comment_comment"
@@ -25,19 +25,9 @@
25
25
  = a.hidden_field :access, :value => Setting.default_access
26
26
  %tr
27
27
  %td
28
- .label
29
- #{t :account}
30
- %span#account_create_title
31
- (#{t :create_new} #{t :or} <a href='#' onclick='crm.select_account(1); return false;'>#{t :select_existing}</a>):
32
- %span#account_select_title
33
- (<a href='#' onclick='crm.create_account(1); return false;'>#{t :create_new}</a> #{t :or} #{t :select_existing}):
34
- %span#account_disabled_title :
35
-
36
- -# Add [-- None --] account choice when editing existing contact that has an account.
37
- - options = {} and (options[:include_blank] = "" unless @contact.new_record? || @contact.account.blank?)
38
- = account_select(options)
39
-
40
- = a.text_field :name, :style => "width:324px; display:none;"
28
+ != account_select_or_create(a) do |options|
29
+ - # Add [-- None --] account choice when editing existing contact that has an account.
30
+ - options[:include_blank] = "" unless @contact.new_record? || @contact.account.blank?
41
31
  %td= spacer
42
32
  %td
43
33
  .label #{t :assigned_to}:
@@ -11,7 +11,7 @@
11
11
  = image_tag("loading.gif", :size => :thumb, :id => "loading", :style => "display: none;")
12
12
  .remote#options{ hidden }
13
13
  .remote#advanced_search{ hidden_if(!params[:q]) }
14
- - if @search
14
+ - if params[:q]
15
15
  = render :partial => "advanced_search"
16
16
 
17
17
  .remote#create_contact{ hidden }
@@ -1,4 +1,4 @@
1
- unless @contacts.blank?
1
+ if @contacts.any?
2
2
  page[:contacts].replace_html render(:partial => "contact", :collection => @contacts)
3
3
  else
4
4
  page[:contacts].replace_html render(:partial => "shared/empty")
@@ -1,7 +1,7 @@
1
1
  :plain
2
- #{I18n.t(:dropbox_ack_intro)}:
2
+ #{I18n.t(:dropbox_notification_intro)}:
3
3
 
4
- #{I18n.t(:dropbox_ack_to)}:
4
+ #{I18n.t(:dropbox_notification_to)}:
5
5
  #{@mediator_links}
6
6
 
7
7
  #{I18n.t(:subject)}: #{@subject}
@@ -10,6 +10,7 @@ if @attached
10
10
  "assigned"
11
11
  end
12
12
  page.insert_html :top, :tasks, :partial => "tasks/#{view}", :collection => [ @attachment ], :locals => { :bucket => @attachment.computed_bucket }
13
+
13
14
  else
14
15
  page.insert_html :top, params[:assets], :partial => "#{params[:assets]}/#{partial}", :collection => [ @attachment ]
15
16
  if called_from_landing_page?(:accounts)
@@ -18,7 +19,6 @@ if @attached
18
19
  page << refresh_sidebar_for(:campaigns, :show, :summary)
19
20
  end
20
21
  end
21
-
22
22
  end
23
23
 
24
24
  page["#{partial}_#{params[:asset_id]}"].visual_effect :highlight, :duration => 1.5
@@ -1,3 +1,3 @@
1
- contacts = @entity.contacts.paginate(:page => params[:page], :per_page => 20)
1
+ contacts = entity.contacts.paginate(:page => params[:page], :per_page => 20)
2
2
  page['contacts'].replace_html :partial => 'contacts/contact', :collection => contacts
3
3
  page['contacts_pagination'].replace_html will_paginate(contacts, :container => false, :params => {:action => :contacts})
@@ -1,3 +1,3 @@
1
- leads = @entity.leads.paginate(:page => params[:page], :per_page => 20)
1
+ leads = entity.leads.paginate(:page => params[:page], :per_page => 20)
2
2
  page['leads'].replace_html :partial => 'leads/lead', :collection => leads
3
3
  page['leads_pagination'].replace_html will_paginate(leads, :container => false, :params => {:action => :leads})
@@ -1,3 +1,3 @@
1
- opportunities = @entity.opportunities.paginate(:page => params[:page], :per_page => 20)
1
+ opportunities = entity.opportunities.paginate(:page => params[:page], :per_page => 20)
2
2
  page['opportunities'].replace_html :partial => 'opportunities/opportunity', :collection => @opportunities
3
3
  page['opportunities_pagination'].replace_html will_paginate(opportunities, :container => false, :params => {:action => :opportunities})
@@ -0,0 +1,4 @@
1
+ class_name = entity.class.name.downcase
2
+ id = "#{class_name}_#{entity.id}_subscribe"
3
+
4
+ page[id].replace :partial => "comments/subscription_links", :locals => {:entity => entity}
@@ -1,3 +1,3 @@
1
- versions = Version.history(@entity).paginate(:page => params[:page], :per_page => 10)
1
+ versions = Version.history(entity).paginate(:page => params[:page], :per_page => 10)
2
2
  page['versions'].replace_html :partial => 'versions/version', :collection => versions
3
3
  page['versions_pagination'].replace_html will_paginate(versions, :container => false, :params => {:action => :versions})
@@ -1,6 +1,6 @@
1
1
  #footer
2
2
  Powered by #{link_to "Fat Free CRM", "http://www.fatfreecrm.com", :"data-popup" => true }
3
- v#{FatFreeCRM::VERSION} &copy; 2008-#{Date.today.year} by Michael Dvorkin
3
+ v#{FatFreeCRM::VERSION::STRING} &copy; 2008-#{Date.today.year} by Michael Dvorkin
4
4
  \|
5
5
  = image_tag "iconset_attribution.png"
6
6
  Icons from the
@@ -20,6 +20,9 @@
20
20
 
21
21
  :javascript
22
22
  #{yield :javascript}
23
+ var _ffcrm_users = [
24
+ #{User.all.map{|u| "\"#{u.full_name} (@#{u.username})\"" }.join(",\n")}
25
+ ];
23
26
 
24
27
  <link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">
25
28
  <link rel="icon" href="/favicon.ico" type="image/x-icon">
@@ -14,6 +14,7 @@
14
14
  %td
15
15
  .label.top #{t :company}:
16
16
  = f.text_field :company
17
+ = autocomplete_text_field 'lead_company', Account.order(:name).map(&:name)
17
18
  %tr
18
19
  %td
19
20
  .label #{t :alt_email}:
@@ -11,7 +11,7 @@
11
11
  = image_tag("loading.gif", :size => :thumb, :id => "loading", :style => "display: none;")
12
12
  .remote#options{ hidden }
13
13
  .remote#advanced_search{ hidden_if(!params[:q]) }
14
- - if @search
14
+ - if params[:q]
15
15
  = render :partial => "advanced_search"
16
16
  .remote#create_lead{ hidden }
17
17
 
@@ -1,4 +1,4 @@
1
- unless @leads.blank?
1
+ if @leads.any?
2
2
  page[:leads].replace_html render @leads
3
3
  else
4
4
  page[:leads].replace_html :partial => "shared/empty"
@@ -35,20 +35,10 @@
35
35
  %table
36
36
  %tr
37
37
  %td
38
- .label
39
- #{t :account}
40
- %span#account_create_title
41
- (#{t :create_new} #{t :or} <a href='#' onclick='crm.select_account(1); return false;'>#{t :select_existing}</a>):
42
- %span#account_select_title
43
- (<a href='#' onclick='crm.create_account(1); return false;'>#{t :create_new}</a> #{t :or} #{t :select_existing}):
44
- %span#account_disabled_title :
45
-
46
- -# Add [-- None --] account choice when editing existing opportunity that has an account.
47
- - options = { :selected => @account.id || 0 }
48
- - options[:include_blank] = true #t(:select_none) unless @opportunity.new_record? || @opportunity.account.blank?
49
- = account_select(options)
50
-
51
- = a.text_field :name, :style => "width:324px; display:none;"
38
+ != account_select_or_create(a) do |options|
39
+ -# Add [-- None --] account choice when editing existing opportunity that has an account.
40
+ - options[:selected] = @account.id || 0
41
+ - options[:include_blank] = true #t(:select_none) unless @opportunity.new_record? || @opportunity.account.blank?
52
42
  %td= spacer
53
43
  %td
54
44
  .label.req #{t :assigned_to}:
@@ -11,7 +11,7 @@
11
11
  = image_tag("loading.gif", :size => :thumb, :id => "loading", :style => "display: none;")
12
12
  .remote#options{ hidden }
13
13
  .remote#advanced_search{ hidden_if(!params[:q]) }
14
- - if @search
14
+ - if params[:q]
15
15
  = render :partial => "advanced_search"
16
16
  .remote#create_opportunity{ hidden }
17
17
 
@@ -1,4 +1,4 @@
1
- unless @opportunities.blank?
1
+ if @opportunities.any?
2
2
  page[:opportunities].replace_html render @opportunities
3
3
  else
4
4
  page[:opportunities].replace_html :partial => "shared/empty"
@@ -0,0 +1,7 @@
1
+ <%= I18n.t('comment_notification.intro', :user_full_name => @user.full_name, :entity_type => @entity_type, :entity_name => @entity_name) %>
2
+
3
+ <%= @comment.comment.html_safe %>
4
+
5
+
6
+ --
7
+ <%= I18n.t('comment_notification.reply_instructions', :entity => @entity_type.downcase) %>: <%= polymorphic_url(@entity) %>
@@ -24,7 +24,9 @@ module FatFreeCRM
24
24
  Dir[Rails.root.join("app/controllers/entities")]
25
25
 
26
26
  # Activate observers that should always be running.
27
- config.active_record.observers = :lead_observer, :opportunity_observer, :task_observer unless ARGV.join.include?('assets:precompile')
27
+ unless ARGV.join.include?('assets:precompile')
28
+ config.active_record.observers = :lead_observer, :opportunity_observer, :task_observer
29
+ end
28
30
 
29
31
  # Load development rake tasks (RSpec, Gem packaging, etc.)
30
32
  rake_tasks do
@@ -15,7 +15,7 @@ if defined?(FatFreeCRM::Application)
15
15
  config.action_controller.perform_caching = false
16
16
 
17
17
  # Don't care if the mailer can't send
18
- config.action_mailer.raise_delivery_errors = false
18
+ config.action_mailer.raise_delivery_errors = true
19
19
 
20
20
  # Print deprecation notices to the Rails logger
21
21
  config.active_support.deprecation = :log
@@ -37,6 +37,9 @@ if defined?(FatFreeCRM::Application)
37
37
 
38
38
  # Print deprecation notices to the stderr
39
39
  config.active_support.deprecation = :stderr
40
+
41
+ # Set default host for mailer specs
42
+ config.action_mailer.default_url_options = { :host => "www.example.com" }
40
43
  end
41
44
 
42
45
  # Optionally load 'awesome_print' for debugging in development mode.
@@ -1,9 +1,12 @@
1
- # Configure ActionMailer
1
+ # Configure ActionMailer unless running tests
2
2
 
3
- # Set SMTP settings if present.
4
- if smtp_settings = Setting.smtp
5
- Rails.application.config.action_mailer.delivery_method = :smtp
6
- Rails.application.config.action_mailer.smtp_settings = smtp_settings
3
+ unless Rails.env.test?
4
+ # Set SMTP settings if present.
5
+ smtp_settings = Setting.smtp || {}
6
+ if smtp_settings["address"].present?
7
+ Rails.application.config.action_mailer.delivery_method = :smtp
8
+ Rails.application.config.action_mailer.smtp_settings = smtp_settings
9
+ end
7
10
  end
8
11
 
9
12
  # Set default host for outgoing emails
@@ -0,0 +1,151 @@
1
+ require 'cancan'
2
+
3
+ # Setup
4
+ # =====
5
+ #
6
+ # Put this gist in Rails.root/config/initializers/cancan.rb
7
+ # Add Squeel to Gemfile, see https://github.com/ernie/squeel
8
+ #
9
+ # gem "squeel", "~> 0.9.3"
10
+ #
11
+ # Load Squeel hash and symbol extensions in squeel config initializer
12
+ #
13
+ # Squeel.configure do |config|
14
+ # config.load_core_extensions :hash, :symbol
15
+ # end
16
+ #
17
+ # then you can write
18
+ #
19
+ # can :manage, User, :permissions.outer => {:type.matches => 'Manage%'}}
20
+ #
21
+ # This should offer all the old MetaWhere capabilities,
22
+ # and extra, also allows outer joins
23
+ #
24
+ # you might also be interested in https://gist.github.com/1012332
25
+ # if you use MetaWhere
26
+
27
+ # https://gist.github.com/1523940
28
+ class String
29
+ include Squeel::Nodes::PredicateOperators
30
+ end
31
+
32
+ module Squeel
33
+ module Visitors
34
+ class PredicateVisitor < Visitor
35
+ def visit_String(o, parent)
36
+ Arel::Nodes::SqlLiteral.new(o)
37
+ end
38
+ end
39
+ end
40
+ end
41
+
42
+ module CanCan
43
+
44
+ module ModelAdapters
45
+ class ActiveRecordAdapter < AbstractAdapter
46
+
47
+ def self.override_condition_matching?(subject, name, value)
48
+ name.kind_of?(Squeel::Nodes::Predicate) if defined? Squeel
49
+ end
50
+
51
+ def self.matches_condition?(subject, name, value)
52
+ subject_value = subject.send(name.expr)
53
+ method_name = name.method_name.to_s
54
+ if method_name.ends_with? "_any"
55
+ value.any? { |v| squeel_match? subject_value, method_name.sub("_any", ""), v }
56
+ elsif method_name.ends_with? "_all"
57
+ value.all? { |v| squeel_match? subject_value, method_name.sub("_all", ""), v }
58
+ else
59
+ squeel_match? subject_value, name.method_name, value
60
+ end
61
+ end
62
+
63
+ def self.squeel_match?(subject_value, method, value)
64
+ case method.to_sym
65
+ when :eq then subject_value == value
66
+ when :not_eq then subject_value != value
67
+ when :in then value.include?(subject_value)
68
+ when :not_in then !value.include?(subject_value)
69
+ when :lt then subject_value < value
70
+ when :lteq then subject_value <= value
71
+ when :gt then subject_value > value
72
+ when :gteq then subject_value >= value
73
+ when :matches then subject_value =~ Regexp.new("^" + Regexp.escape(value).gsub("%", ".*") + "$", true)
74
+ when :does_not_match then !squeel_match?(subject_value, :matches, value)
75
+ else raise NotImplemented, "The #{method} Squeel condition is not supported."
76
+ end
77
+ end
78
+
79
+ # mostly let Squeel do the job in building the query
80
+ def conditions
81
+ if @rules.size == 1 && @rules.first.base_behavior
82
+ # Return the conditions directly if there's just one definition
83
+ @rules.first.conditions.dup
84
+ else
85
+ @rules.reverse.inject(false_sql) do |accumulator, rule|
86
+ conditions = rule.conditions.dup
87
+ if conditions.blank?
88
+ rule.base_behavior ? (accumulator | true_sql) : (accumulator & false_sql)
89
+ else
90
+ rule.base_behavior ? (accumulator | conditions) : (accumulator & -conditions)
91
+ end
92
+ end
93
+ end
94
+ end
95
+
96
+ private
97
+
98
+ # override to fix overwrites
99
+ # do not write existing hashes using empty hashes
100
+ def merge_joins(base, add)
101
+ add.each do |name, nested|
102
+ if base[name].is_a?(Hash) && nested.present?
103
+ merge_joins(base[name], nested)
104
+ elsif !base[name].is_a?(Hash) || nested.present?
105
+ base[name] = nested
106
+ end
107
+ end
108
+ end
109
+
110
+ end
111
+ end
112
+
113
+ class Rule
114
+ # allow Squeel
115
+ def matches_conditions_hash?(subject, conditions = @conditions)
116
+ if conditions.empty?
117
+ true
118
+ else
119
+ if model_adapter(subject).override_conditions_hash_matching? subject, conditions
120
+ model_adapter(subject).matches_conditions_hash? subject, conditions
121
+ else
122
+ conditions.all? do |name, value|
123
+ if model_adapter(subject).override_condition_matching? subject, name, value
124
+ model_adapter(subject).matches_condition? subject, name, value
125
+ else
126
+ method_name = case name
127
+ when Symbol then name
128
+ when Squeel::Nodes::Join then name._name
129
+ when Squeel::Nodes::Predicate then name.expr
130
+ else raise name
131
+ end
132
+ attribute = subject.send(method_name)
133
+ if value.kind_of?(Hash)
134
+ if attribute.kind_of? Array
135
+ attribute.any? { |element| matches_conditions_hash? element, value }
136
+ else
137
+ !attribute.nil? && matches_conditions_hash?(attribute, value)
138
+ end
139
+ elsif value.kind_of?(Array) || value.kind_of?(Range)
140
+ value.include? attribute
141
+ else
142
+ attribute == value
143
+ end
144
+ end
145
+ end
146
+ end
147
+ end
148
+ end
149
+ end
150
+
151
+ end
@@ -0,0 +1 @@
1
+ ENTITIES = %w(Account Campaign Contact Lead Opportunity).freeze
@@ -0,0 +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
+
18
+ # Set default locale from Settings
19
+
20
+ I18n.default_locale = Setting.locale
@@ -1,11 +1,10 @@
1
1
  require 'paper_trail'
2
2
 
3
- Version.class_eval do
3
+ Version.const_set :ASSETS, %w(all tasks campaigns leads accounts contacts opportunities comments emails)
4
+ Version.const_set :EVENTS, %w(all_events create view update destroy)
5
+ Version.const_set :DURATION, %w(one_hour one_day two_days one_week two_weeks one_month)
4
6
 
5
- ASSETS = %w(all tasks campaigns leads accounts contacts opportunities comments emails)
6
- EVENTS = %w(all_events create view update destroy)
7
- DURATION = %w(one_hour one_day two_days one_week two_weeks one_month)
8
- ENTITIES = %w(Account Campaign Contact Lead Opportunity)
7
+ Version.class_eval do
9
8
 
10
9
  attr_accessible :related
11
10
  belongs_to :related, :polymorphic => true