fat_free_crm 0.22.1 → 0.23.0

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 (40) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/crm_textarea_autocomplete.js.coffee +6 -9
  3. data/app/controllers/admin/fields_controller.rb +2 -2
  4. data/app/controllers/application_controller.rb +1 -1
  5. data/app/controllers/emails_controller.rb +1 -1
  6. data/app/controllers/entities/contacts_controller.rb +1 -1
  7. data/app/controllers/users_controller.rb +15 -3
  8. data/app/helpers/application_helper.rb +1 -1
  9. data/app/helpers/leads_helper.rb +1 -1
  10. data/app/helpers/opportunities_helper.rb +1 -1
  11. data/app/models/entities/campaign.rb +1 -1
  12. data/app/models/observers/lead_observer.rb +2 -1
  13. data/app/models/observers/task_observer.rb +2 -1
  14. data/app/models/polymorphic/address.rb +2 -1
  15. data/app/models/polymorphic/comment.rb +3 -4
  16. data/app/models/polymorphic/task.rb +1 -1
  17. data/app/models/users/user.rb +7 -1
  18. data/app/views/layouts/application.html.haml +1 -3
  19. data/config/application.rb +2 -0
  20. data/config/database.yml +9 -11
  21. data/config/environments/development.rb +15 -0
  22. data/config/initializers/application_controller_renderer.rb +1 -0
  23. data/config/initializers/backtrace_silencers.rb +1 -0
  24. data/config/initializers/content_security_policy.rb +1 -0
  25. data/config/initializers/devise.rb +1 -0
  26. data/config/initializers/inflections.rb +1 -0
  27. data/config/initializers/permissions_policy.rb +1 -0
  28. data/config/routes.rb +1 -3
  29. data/db/fat_free_crm_development.sqlite3 +0 -0
  30. data/db/fat_free_crm_test.sqlite3 +0 -0
  31. data/db/migrate/20230422234321_optionally_create_action_text_tables.action_text.rb +29 -0
  32. data/db/migrate/20230526211831_create_active_storage_tables.active_storage.rb +3 -3
  33. data/db/migrate/20230526212613_convert_to_active_storage.rb +10 -13
  34. data/db/schema.rb +16 -9
  35. data/db/seeds.rb +1 -0
  36. data/lib/fat_free_crm/callback.rb +0 -1
  37. data/lib/fat_free_crm/core_ext/string.rb +1 -1
  38. data/lib/fat_free_crm/mail_processor/base.rb +6 -10
  39. data/lib/fat_free_crm/version.rb +2 -2
  40. metadata +6 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6ed29c049db6b4f6c31a7c1f5a3a083c1ab92a87d1475ae0808777a8d5c87c9d
4
- data.tar.gz: ea1c36a463eafd3c50db26e072a447e74a8d07095a9bd19d0149096f681dc36b
3
+ metadata.gz: 170884fee8c43222891b33e09f6a1996c6a33c70cf5839de3eae5ab987340ef1
4
+ data.tar.gz: d1f638adddae45577b72fc71d24b88f1ec7ca8513b98ae2a29ba9977ea5b5c28
5
5
  SHA512:
6
- metadata.gz: 31bf4871e24767881af295b9b686a62b5c7de6d56894d67f13af38d6721f8728b36d3a0535b05a9b7f14ebbc65d5648ee4dd9924ded07fcf3308fe04835ea428
7
- data.tar.gz: 71240615f55f2e0ac3527223d240470d28c3ada768a5f7240c4aea3a1b976ced11e10a2d4335cd733971ba526719f06ff44b7a15ca41127bb63aea7dbc5dd4ab
6
+ metadata.gz: e5284a4f39f18595dfb12b87acf4052fb464a432675959f3c0e58a6edb3eeb59899e11bcff8433e3f251656bba35eea6e5f0abde513d4dc56c1c3fce98f576d3
7
+ data.tar.gz: 5644a00f3ebf9db88505d686591856d8614c4ac7908bf484fe5147494b656aacda669e236fcabdce48801d9e96cf19454b22f586aa2902ffb3e70c3bffd75a32
@@ -17,17 +17,14 @@
17
17
 
18
18
  # Only autocomplete if search term starts with '@'
19
19
  return [] unless text.indexOf("@") is 0
20
- words = []
21
- i = 0
22
-
23
- while i < _ffcrm_users.length
24
- name_query = text.replace("@", "").toLowerCase()
25
- words.push _ffcrm_users[i] unless _ffcrm_users[i].toLowerCase().indexOf(name_query) is -1
26
- i++
27
- cb words, text.replace("@", "")
20
+ $.ajax
21
+ url: "/users/auto_complete"
22
+ data:
23
+ term: text.replace("@", "")
24
+ success: (response) ->
25
+ cb response, text.replace("@", "")
28
26
 
29
27
  selected: (text, data) ->
30
28
  username_regEx = new RegExp("\\((@[^)]+)\\)")
31
29
  text.match(username_regEx)[1]
32
-
33
30
  ) jQuery
@@ -42,7 +42,7 @@ class Admin::FieldsController < Admin::ApplicationController
42
42
  #----------------------------------------------------------------------------
43
43
  def create
44
44
  as = field_params["as"]
45
- klass= Field.lookup_class(as).safe_constantize
45
+ klass = Field.lookup_class(as).safe_constantize
46
46
  @field =
47
47
  if as.match?(/pair/)
48
48
  klass.create_pair("pair" => pair_params, "field" => field_params).first
@@ -117,7 +117,7 @@ class Admin::FieldsController < Admin::ApplicationController
117
117
  end
118
118
 
119
119
  def pair_params
120
- params.require(:pair).permit("0": [:hint, :required, :disabled, :id], "1": [:hint, :required, :disabled, :id])
120
+ params.require(:pair).permit("0": %i[hint required disabled id], "1": %i[hint required disabled id])
121
121
  end
122
122
 
123
123
  def setup_current_tab
@@ -79,7 +79,7 @@ class ApplicationController < ActionController::Base
79
79
  # See http://blog.nvisium.com/2014/09/understanding-protectfromforgery.html for more details.
80
80
  #----------------------------------------------------------------------------
81
81
  def handle_unverified_request
82
- raise ActionController::InvalidAuthenticityToken
82
+ raise ActionController::InvalidAuthenticityToken unless ENV.fetch('CODESPACE_NAME', nil) && Rails.env.development?
83
83
  end
84
84
 
85
85
  #
@@ -15,6 +15,6 @@ class EmailsController < ApplicationController
15
15
  @email.destroy
16
16
  respond_with(@email)
17
17
  end
18
-
18
+
19
19
  ActiveSupport.run_load_hooks(:fat_free_crm_emails_controller, self)
20
20
  end
@@ -164,6 +164,6 @@ class ContactsController < EntitiesController
164
164
  redirect_to contacts_path
165
165
  end
166
166
  end
167
-
167
+
168
168
  ActiveSupport.run_load_hooks(:fat_free_crm_contacts_controller, self)
169
169
  end
@@ -63,9 +63,7 @@ class UsersController < ApplicationController
63
63
  end
64
64
  end
65
65
  responds_to_parent do
66
- # Without return RSpec2 screams bloody murder about rendering twice:
67
- # within the block and after yield in responds_to_parent.
68
- render && (return if Rails.env.test?)
66
+ render
69
67
  end
70
68
  end
71
69
  end
@@ -111,6 +109,20 @@ class UsersController < ApplicationController
111
109
  @unassigned_opportunities = Opportunity.my(current_user).unassigned.pipeline.order(:stage).includes(:account, :user, :tags)
112
110
  end
113
111
 
112
+ def auto_complete
113
+ @query = params[:term] || ''
114
+ @users = User.my(current_user).text_search(@query).limit(10).order(:first_name, :last_name)
115
+
116
+ respond_to do |format|
117
+ format.json do
118
+ results = @users.map do |a|
119
+ helpers.j(a.full_name + " (@" + a.username + ")")
120
+ end
121
+ render json: results
122
+ end
123
+ end
124
+ end
125
+
114
126
  protected
115
127
 
116
128
  def user_params
@@ -155,7 +155,7 @@ module ApplicationHelper
155
155
  #----------------------------------------------------------------------------
156
156
  def link_to_email(email, length = nil, &_block)
157
157
  name = (length ? truncate(email, length: length) : email)
158
- bcc = Setting&.email_dropbox
158
+ bcc = Setting.email_dropbox
159
159
  mailto = if bcc && bcc[:address].present?
160
160
  "#{email}?bcc=#{bcc[:address]}"
161
161
  else
@@ -69,7 +69,7 @@ module LeadsHelper
69
69
  #----------------------------------------------------------------------------
70
70
  def lead_summary(lead)
71
71
  summary = []
72
- summary << (lead.status ? t(lead.status) : t(:other))
72
+ summary << t(lead.status || :other)
73
73
 
74
74
  if lead.company? && lead.title?
75
75
  summary << t(:works_at, job_title: lead.title, company: lead.company)
@@ -17,7 +17,7 @@ module OpportunitiesHelper
17
17
  def opportunity_summary(opportunity)
18
18
  summary = []
19
19
  amount = []
20
- summary << (opportunity.stage ? t(opportunity.stage) : t(:other))
20
+ summary << t(opportunity.stage || :other)
21
21
  summary << number_to_currency(opportunity.weighted_amount, precision: 0)
22
22
  unless %w[won lost].include?(opportunity.stage)
23
23
  amount << number_to_currency(opportunity.amount.to_f, precision: 0)
@@ -103,7 +103,7 @@ class Campaign < ActiveRecord::Base
103
103
  # Make sure end date > start date.
104
104
  #----------------------------------------------------------------------------
105
105
  def start_and_end_dates
106
- errors.add(:ends_on, :dates_not_in_sequence) if (starts_on && ends_on) && (starts_on > ends_on)
106
+ errors.add(:ends_on, :dates_not_in_sequence) if starts_on && ends_on && (starts_on > ends_on)
107
107
  end
108
108
 
109
109
  # Make sure at least one user has been selected if the campaign is being shared.
@@ -16,7 +16,8 @@ class LeadObserver < ActiveRecord::Observer
16
16
 
17
17
  def after_update(item)
18
18
  original = @@leads.delete(item.id)
19
- return log_activity(item, :reject) if original&.status != "rejected" && item.status == "rejected"
19
+
20
+ log_activity(item, :reject) if original&.status != "rejected" && item.status == "rejected"
20
21
  end
21
22
 
22
23
  private
@@ -19,7 +19,8 @@ class TaskObserver < ActiveRecord::Observer
19
19
  if original
20
20
  return log_activity(item, :complete) if item.completed_at && original.completed_at.nil?
21
21
  return log_activity(item, :reassign) if item.assigned_to != original.assigned_to
22
- return log_activity(item, :reschedule) if item.bucket != original.bucket
22
+
23
+ log_activity(item, :reschedule) if item.bucket != original.bucket
23
24
  end
24
25
  end
25
26
 
@@ -54,7 +54,8 @@ class Address < ActiveRecord::Base
54
54
  exists = attributes['id'].present?
55
55
  empty = %w[street1 street2 city state zipcode country full_address].map { |name| attributes[name].blank? }.all?
56
56
  attributes[:_destroy] = 1 if exists && empty
57
- (!exists && empty)
57
+
58
+ !exists && empty
58
59
  end
59
60
 
60
61
  ActiveSupport.run_load_hooks(:fat_free_crm_address, self)
@@ -52,10 +52,9 @@ class Comment < ActiveRecord::Base
52
52
 
53
53
  # Notify subscribed users when a comment is added, unless user created this comment
54
54
  def notify_subscribers
55
- commentable.subscribed_users.reject { |user_id| user_id == user.id }.each do |subscriber_id|
56
- if subscriber = User.find_by_id(subscriber_id)
57
- SubscriptionMailer.comment_notification(subscriber, self).deliver_later
58
- end
55
+ users_to_notify = User.where(id: commentable.subscribed_users.reject { |user_id| user_id == user.id })
56
+ users_to_notify.select(&:emailable?).each do |subscriber|
57
+ SubscriptionMailer.comment_notification(subscriber, self).deliver_later
59
58
  end
60
59
  end
61
60
 
@@ -103,7 +103,7 @@ class Task < ActiveRecord::Base
103
103
  scope :completed_last_month, -> { where('completed_at >= ? AND completed_at < ?', (Time.zone.now.beginning_of_month.utc - 1.day).beginning_of_month.utc, Time.zone.now.beginning_of_month.utc) }
104
104
 
105
105
  scope :text_search, lambda { |query|
106
- query = query.gsub(/[^\w\s\-\.'\p{L}]/u, '').strip
106
+ query = query.gsub(/[^\w\s\-.'\p{L}]/u, '').strip
107
107
  where('upper(name) LIKE upper(?)', "%#{query}%")
108
108
  }
109
109
 
@@ -73,7 +73,7 @@ class User < ActiveRecord::Base
73
73
  scope :by_name, -> { order('first_name, last_name, email') }
74
74
 
75
75
  scope :text_search, lambda { |query|
76
- query = query.gsub(/[^\w\s\-\.'\p{L}]/u, '').strip
76
+ query = query.gsub(/[^\w\s\-.'\p{L}]/u, '').strip
77
77
  where('upper(username) LIKE upper(:s) OR upper(email) LIKE upper(:s) OR upper(first_name) LIKE upper(:s) OR upper(last_name) LIKE upper(:s)', s: "%#{query}%")
78
78
  }
79
79
 
@@ -134,6 +134,12 @@ class User < ActiveRecord::Base
134
134
  end
135
135
  end
136
136
 
137
+ # Send emails to active users only
138
+ #----------------------------------------------------------------------------
139
+ def emailable?
140
+ confirmed? && !awaits_approval? && !suspended? && email.present?
141
+ end
142
+
137
143
  #----------------------------------------------------------------------------
138
144
  def preference
139
145
  @preference ||= preferences.build
@@ -26,9 +26,7 @@
26
26
  - if current_user.present?
27
27
  :javascript
28
28
  #{yield :javascript}
29
- var _ffcrm_users = [
30
- #{raw User.all.map{|u| "'#{j u.full_name} (@#{j u.username})'" }.join(",\n")}
31
- ];
29
+
32
30
 
33
31
  <link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">
34
32
  <link rel="icon" href="/favicon.ico" type="image/x-icon">
@@ -85,6 +85,8 @@ module FatFreeCRM
85
85
  ::ActiveSupport::HashWithIndifferentAccess, # for Field#settings serialization see app/models/fields/field.rb
86
86
  ::ActiveSupport::TimeWithZone,
87
87
  ::ActiveSupport::TimeZone,
88
+ ::ActsAsTaggableOn::TagList,
89
+ ::ActsAsTaggableOn::DefaultParser,
88
90
  ::BigDecimal,
89
91
  ::Date,
90
92
  ::Symbol,
data/config/database.yml CHANGED
@@ -1,25 +1,23 @@
1
+ # SQLite version 3.x
2
+ # gem install sqlite3-ruby (not necessary on OS X Leopard)
1
3
  ---
2
4
  development: &development
3
- adapter: postgresql
4
- database: fat_free_crm_development
5
- username: postgres
6
- password: postgres
7
- host: localhost
8
- port: 5432
9
- schema_search_path: public
10
- min_messages: warning
5
+ adapter: sqlite3
6
+ database: db/fat_free_crm_development.sqlite3
7
+ pool: 5
8
+ timeout: 5000
11
9
 
12
10
  # Warning: The database defined as "test" will be erased and
13
11
  # re-generated from your development database when you run "rake".
14
12
  # Do not set this db to the same as development or production.
15
13
  test:
16
14
  <<: *development
17
- database: fat_free_crm_test
15
+ database: db/fat_free_crm_test.sqlite3
18
16
 
19
17
  production:
20
18
  <<: *development
21
- database: fat_free_crm_production
19
+ database: db/fat_free_crm_production.sqlite3
22
20
 
23
21
  staging:
24
22
  <<: *development
25
- database: fat_free_crm_staging
23
+ database: db/fat_free_crm_staging.sqlite3
@@ -83,5 +83,20 @@ if defined?(FatFreeCRM::Application)
83
83
  # Checks for improperly declared sprockets dependencies.
84
84
  # Raises helpful error messages.
85
85
  config.assets.raise_runtime_errors = true
86
+
87
+ # Are we running in a GitHub Codespace?
88
+ if ENV.fetch('CODESPACE_NAME', nil)
89
+ config.host = "#{ENV.fetch('CODESPACE_NAME', nil)}-3000.app.github.dev:443"
90
+ config.hosts << ".preview.app.github.dev"
91
+ config.hosts << ".app.github.dev"
92
+
93
+ config.force_ssl = true
94
+ config.action_dispatch.cookies_same_site_protection = :lax
95
+
96
+ config.action_dispatch.trusted_proxies = [
97
+ # Trust all IPs (safe in dev only)
98
+ IPAddr.new("0.0.0.0/0"), IPAddr.new("::/0")
99
+ ]
100
+ end
86
101
  end
87
102
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  # Be sure to restart your server when you modify this file.
3
4
 
4
5
  # ActiveSupport::Reloader.to_prepare do
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  # Be sure to restart your server when you modify this file.
3
4
 
4
5
  # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces.
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  # Be sure to restart your server when you modify this file.
3
4
 
4
5
  # Define an application-wide content security policy.
@@ -16,6 +16,7 @@ Devise.setup do |config|
16
16
  # Devise will use the `secret_key_base` as its `secret_key`
17
17
  # by default. You can change it below and use your own secret key.
18
18
  # config.secret_key = SecureRandom.hex(64)
19
+ config.secret_key = Rails.application.secret_key_base
19
20
 
20
21
  # ==> Mailer Configuration
21
22
  # Configure the e-mail address which will be shown in Devise::Mailer,
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  # Be sure to restart your server when you modify this file.
3
4
 
4
5
  # Add new inflection rules using the following format. Inflections
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  # Define an application-wide HTTP permissions policy. For further
3
4
  # information see https://developers.google.com/web/updates/2018/06/feature-policy
4
5
  #
data/config/routes.rb CHANGED
@@ -23,6 +23,7 @@ Rails.application.routes.draw do
23
23
  resources :users, only: %i[index show] do
24
24
  collection do
25
25
  get :opportunities_overview
26
+ match :auto_complete, via: %i[get post]
26
27
  end
27
28
  end
28
29
  end
@@ -159,9 +160,6 @@ Rails.application.routes.draw do
159
160
  patch :change_password
160
161
  post :redraw
161
162
  end
162
- collection do
163
- match :auto_complete, via: %i[get post]
164
- end
165
163
  end
166
164
 
167
165
  namespace :admin do
Binary file
File without changes
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This migration comes from action_text (originally 20180528164100)
4
+ class OptionallyCreateActionTextTables < ActiveRecord::Migration[6.0]
5
+ def change
6
+ # Use Active Record's configured type for primary and foreign keys
7
+ primary_key_type, foreign_key_type = primary_and_foreign_key_types
8
+
9
+ create_table :action_text_rich_texts, id: primary_key_type, if_not_exists: true do |t|
10
+ t.string :name, null: false
11
+ t.text :body, size: :long
12
+ t.references :record, null: false, polymorphic: true, index: false, type: foreign_key_type
13
+
14
+ t.timestamps
15
+
16
+ t.index %i[record_type record_id name], name: "index_action_text_rich_texts_uniqueness", unique: true
17
+ end
18
+ end
19
+
20
+ private
21
+
22
+ def primary_and_foreign_key_types
23
+ config = Rails.configuration.generators
24
+ setting = config.options[config.orm][:primary_key_type]
25
+ primary_key_type = setting || :primary_key
26
+ foreign_key_type = setting || :bigint
27
+ [primary_key_type, foreign_key_type]
28
+ end
29
+ end
@@ -6,7 +6,7 @@ class CreateActiveStorageTables < ActiveRecord::Migration[5.2]
6
6
  # Use Active Record's configured type for primary and foreign keys
7
7
  primary_key_type, foreign_key_type = primary_and_foreign_key_types
8
8
 
9
- create_table :active_storage_blobs, id: primary_key_type do |t|
9
+ create_table :active_storage_blobs, id: primary_key_type, if_not_exists: true do |t|
10
10
  t.string :key, null: false
11
11
  t.string :filename, null: false
12
12
  t.string :content_type
@@ -19,7 +19,7 @@ class CreateActiveStorageTables < ActiveRecord::Migration[5.2]
19
19
  t.index [:key], unique: true
20
20
  end
21
21
 
22
- create_table :active_storage_attachments, id: primary_key_type do |t|
22
+ create_table :active_storage_attachments, id: primary_key_type, if_not_exists: true do |t|
23
23
  t.string :name, null: false
24
24
  t.references :record, null: false, polymorphic: true, index: false, type: foreign_key_type
25
25
  t.references :blob, null: false, type: foreign_key_type
@@ -30,7 +30,7 @@ class CreateActiveStorageTables < ActiveRecord::Migration[5.2]
30
30
  t.foreign_key :active_storage_blobs, column: :blob_id
31
31
  end
32
32
 
33
- create_table :active_storage_variant_records, id: primary_key_type do |t|
33
+ create_table :active_storage_variant_records, id: primary_key_type, if_not_exists: true do |t|
34
34
  t.belongs_to :blob, null: false, index: false, type: foreign_key_type
35
35
  t.string :variation_digest, null: false
36
36
 
@@ -4,19 +4,16 @@ class ConvertToActiveStorage < ActiveRecord::Migration[5.2]
4
4
  require 'open-uri'
5
5
 
6
6
  def up
7
- get_blob_id = case ENV['CI'] && ENV['DB']
8
- when 'sqlite'
9
- 'LAST_INSERT_ROWID()'
10
- when 'mysql'
11
- 'LAST_INSERT_ID()'
12
- when 'postgres'
13
- 'LASTVAL()'
14
- else
15
- 'LASTVAL()'
16
- end
17
-
18
7
  ActiveRecord::Base.connection.raw_connection.then do |conn|
8
+ get_blob_id = case ENV['CI'] && ENV['DB']
9
+ when 'mysql'
10
+ 'LAST_INSERT_ID()'
11
+ else
12
+ 'LASTVAL()'
13
+ end
14
+ get_blob_id = 'LAST_INSERT_ROWID()' if conn.is_a?(SQLite3::Database)
19
15
  if conn.is_a?(::PG::Connection)
16
+ get_blob_id = 'LASTVAL()'
20
17
  conn.prepare('active_storage_blobs', <<-SQL)
21
18
  INSERT INTO active_storage_blobs (
22
19
  key, filename, content_type, metadata, byte_size, checksum, created_at
@@ -29,13 +26,13 @@ class ConvertToActiveStorage < ActiveRecord::Migration[5.2]
29
26
  ) VALUES ($1, $2, $3, #{get_blob_id}, $4)
30
27
  SQL
31
28
  else
32
- conn.raw_connection.prepare(<<-SQL)
29
+ conn.prepare(<<-SQL)
33
30
  INSERT INTO active_storage_blobs (
34
31
  `key`, filename, content_type, metadata, byte_size, checksum, created_at
35
32
  ) VALUES (?, ?, ?, '{}', ?, ?, ?)
36
33
  SQL
37
34
 
38
- conn.raw_connection.prepare(<<-SQL)
35
+ conn.prepare(<<-SQL)
39
36
  INSERT INTO active_storage_attachments (
40
37
  name, record_type, record_id, blob_id, created_at
41
38
  ) VALUES (?, ?, ?, #{get_blob_id}, ?)
data/db/schema.rb CHANGED
@@ -11,9 +11,6 @@
11
11
  # It's strongly recommended that you check this file into your version control system.
12
12
 
13
13
  ActiveRecord::Schema[7.0].define(version: 2023_05_26_212613) do
14
- # These are extensions that must be enabled in order to support this database
15
- enable_extension "plpgsql"
16
-
17
14
  create_table "account_contacts", force: :cascade do |t|
18
15
  t.integer "account_id"
19
16
  t.integer "contact_id"
@@ -55,6 +52,16 @@ ActiveRecord::Schema[7.0].define(version: 2023_05_26_212613) do
55
52
  t.index ["user_id", "name", "deleted_at"], name: "index_accounts_on_user_id_and_name_and_deleted_at", unique: true
56
53
  end
57
54
 
55
+ create_table "action_text_rich_texts", force: :cascade do |t|
56
+ t.string "name", null: false
57
+ t.text "body"
58
+ t.string "record_type", null: false
59
+ t.bigint "record_id", null: false
60
+ t.datetime "created_at", null: false
61
+ t.datetime "updated_at", null: false
62
+ t.index ["record_type", "record_id", "name"], name: "index_action_text_rich_texts_uniqueness", unique: true
63
+ end
64
+
58
65
  create_table "active_storage_attachments", force: :cascade do |t|
59
66
  t.string "name", null: false
60
67
  t.string "record_type", null: false
@@ -247,12 +254,12 @@ ActiveRecord::Schema[7.0].define(version: 2023_05_26_212613) do
247
254
  t.text "collection"
248
255
  t.boolean "disabled"
249
256
  t.boolean "required"
250
- t.integer "maxlength"
257
+ t.integer "maxlength", limit: 4
251
258
  t.datetime "created_at", precision: nil
252
259
  t.datetime "updated_at", precision: nil
253
260
  t.integer "pair_id"
254
261
  t.text "settings"
255
- t.integer "minlength", default: 0
262
+ t.integer "minlength", limit: 4, default: 0
256
263
  t.string "pattern"
257
264
  t.string "autofocus"
258
265
  t.string "autocomplete"
@@ -417,7 +424,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_05_26_212613) do
417
424
 
418
425
  create_table "users", force: :cascade do |t|
419
426
  t.string "username", limit: 32, default: "", null: false
420
- t.string "email", limit: 254, default: "", null: false
427
+ t.string "email", limit: 254
421
428
  t.string "first_name", limit: 32
422
429
  t.string "last_name", limit: 32
423
430
  t.string "title", limit: 64
@@ -448,8 +455,8 @@ ActiveRecord::Schema[7.0].define(version: 2023_05_26_212613) do
448
455
  t.datetime "remember_created_at", precision: nil
449
456
  t.string "authentication_token"
450
457
  t.string "confirmation_token", limit: 255
451
- t.datetime "confirmed_at", precision: nil
452
- t.datetime "confirmation_sent_at", precision: nil
458
+ t.datetime "confirmed_at"
459
+ t.datetime "confirmation_sent_at"
453
460
  t.index ["authentication_token"], name: "index_users_on_authentication_token", unique: true
454
461
  t.index ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true
455
462
  t.index ["email"], name: "index_users_on_email"
@@ -461,7 +468,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_05_26_212613) do
461
468
  create_table "versions", force: :cascade do |t|
462
469
  t.string "item_type", null: false
463
470
  t.integer "item_id", null: false
464
- t.string "event", limit: 512, null: false
471
+ t.string "event", limit: 512
465
472
  t.string "whodunnit"
466
473
  t.text "object"
467
474
  t.datetime "created_at", precision: nil
data/db/seeds.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  # This file should contain all the record creation needed to seed the database with its default values.
3
4
  # The data can then be loaded with the rake db:seed (or created alongside the db with db:setup).
4
5
  #
@@ -108,7 +108,6 @@ module FatFreeCRM
108
108
  #--------------------------------------------------------------------------
109
109
  module Helper
110
110
  def hook(method, caller, context = {}, &block)
111
-
112
111
  # In a view template context, hooks are able to replace, append or prepend content.
113
112
  if caller.is_a?(ActionView::Base)
114
113
  hooks = FatFreeCRM::Callback.view_hook(method, caller, context)
@@ -36,7 +36,7 @@ class String
36
36
  # A query with 4 words will generate 6 permutations
37
37
  def name_permutations
38
38
  parts = split(" ")
39
- Array.new((parts.size - 1)) do |i|
39
+ Array.new(parts.size - 1) do |i|
40
40
  # ["A", "B", "C", "D"] => [["A B C", "D"], ["A B", "C D"], ["A", "B C D"]]
41
41
  [parts[(0..i)].join(" "), parts[(i + 1)..-1].join(" ")]
42
42
  end.each_with_object([]) do |perm, arr|
@@ -104,10 +104,8 @@ module FatFreeCRM
104
104
  discard(uid)
105
105
  end
106
106
  rescue Exception => e
107
- if %w[test development].include?(Rails.env)
108
- warn e
109
- warn e.backtrace
110
- end
107
+ warn e
108
+ warn e.backtrace
111
109
  log "error processing email: #{e.inspect}", email
112
110
  discard(uid)
113
111
  end
@@ -181,12 +179,10 @@ module FatFreeCRM
181
179
  # Centralized logging.
182
180
  #--------------------------------------------------------------------------------------
183
181
  def log(message, email = nil)
184
- unless %w[test cucumber].include?(Rails.env)
185
- klass = self.class.to_s.split("::").last
186
- klass << " [Dry Run]" if @dry_run
187
- puts "[#{Time.now.rfc822}] #{klass}: #{message}"
188
- puts "[#{Time.now.rfc822}] #{klass}: From: #{email.from}, Subject: #{email.subject} (#{email.message_id})" if email
189
- end
182
+ klass = self.class.to_s.split("::").last
183
+ klass << " [Dry Run]" if @dry_run
184
+ Rails.logger.info("[#{Time.now.rfc822}] #{klass}: #{message}")
185
+ Rails.logger.info("[#{Time.now.rfc822}] #{klass}: From: #{email.from}, Subject: #{email.subject} (#{email.message_id})") if email
190
186
  end
191
187
 
192
188
  # Returns the plain-text version of an email, or strips html tags
@@ -8,8 +8,8 @@
8
8
  module FatFreeCRM
9
9
  module VERSION # :nodoc:
10
10
  MAJOR = 0
11
- MINOR = 22
12
- TINY = 1
11
+ MINOR = 23
12
+ TINY = 0
13
13
  PRE = nil
14
14
 
15
15
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
metadata CHANGED
@@ -1,16 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fat_free_crm
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.22.1
4
+ version: 0.23.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Dvorkin
8
8
  - Stephen Kenworthy
9
9
  - Daniel O'Connor
10
- autorequire:
11
10
  bindir: bin
12
11
  cert_chain: []
13
- date: 2024-08-28 00:00:00.000000000 Z
12
+ date: 1980-01-02 00:00:00.000000000 Z
14
13
  dependencies:
15
14
  - !ruby/object:Gem::Dependency
16
15
  name: rails
@@ -1090,6 +1089,8 @@ files:
1090
1089
  - db/demo/settings.yml
1091
1090
  - db/demo/tasks.yml
1092
1091
  - db/demo/users.yml
1092
+ - db/fat_free_crm_development.sqlite3
1093
+ - db/fat_free_crm_test.sqlite3
1093
1094
  - db/migrate/20100928030598_create_sessions.rb
1094
1095
  - db/migrate/20100928030599_create_users.rb
1095
1096
  - db/migrate/20100928030600_create_openid_tables.rb
@@ -1162,6 +1163,7 @@ files:
1162
1163
  - db/migrate/20180107082701_authlogic_to_devise.rb
1163
1164
  - db/migrate/20200806004152_add_pattern_to_fields.rb
1164
1165
  - db/migrate/20200806004459_add_html5_to_fields.rb
1166
+ - db/migrate/20230422234321_optionally_create_action_text_tables.action_text.rb
1165
1167
  - db/migrate/20230526211831_create_active_storage_tables.active_storage.rb
1166
1168
  - db/migrate/20230526212613_convert_to_active_storage.rb
1167
1169
  - db/schema.rb
@@ -1314,7 +1316,6 @@ homepage: http://fatfreecrm.com
1314
1316
  licenses:
1315
1317
  - MIT
1316
1318
  metadata: {}
1317
- post_install_message:
1318
1319
  rdoc_options: []
1319
1320
  require_paths:
1320
1321
  - lib
@@ -1329,8 +1330,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
1329
1330
  - !ruby/object:Gem::Version
1330
1331
  version: '0'
1331
1332
  requirements: []
1332
- rubygems_version: 3.5.9
1333
- signing_key:
1333
+ rubygems_version: 3.6.9
1334
1334
  specification_version: 4
1335
1335
  summary: Fat Free CRM
1336
1336
  test_files: []