# Copyright (c) 2008-2013 Michael Dvorkin and contributors. # # Fat Free CRM is freely distributable under the terms of MIT license. # See MIT-LICENSE file or http://www.opensource.org/licenses/mit-license.php #------------------------------------------------------------------------------ # == Schema Information # # Table name: campaigns # # id :integer not null, primary key # user_id :integer # assigned_to :integer # name :string(64) default(""), not null # access :string(8) default("Public") # status :string(64) # budget :decimal(12, 2) # target_leads :integer # target_conversion :float # target_revenue :decimal(12, 2) # leads_count :integer # opportunities_count :integer # revenue :decimal(12, 2) # starts_on :date # ends_on :date # objectives :text # deleted_at :datetime # created_at :datetime # updated_at :datetime # background_info :string(255) # class Campaign < ActiveRecord::Base belongs_to :user belongs_to :assignee, class_name: "User", foreign_key: :assigned_to has_many :tasks, as: :asset, dependent: :destroy # , :order => 'created_at DESC' has_many :leads, -> { order "id DESC" }, dependent: :destroy has_many :opportunities, -> { order "id DESC" }, dependent: :destroy has_many :emails, as: :mediator serialize :subscribed_users, Set scope :state, ->(filters) { where('status IN (?)' + (filters.delete('other') ? ' OR status IS NULL' : ''), filters) } scope :created_by, ->(user) { where(user_id: user.id) } scope :assigned_to, ->(user) { where(assigned_to: user.id) } scope :text_search, ->(query) { search('name_cont' => query).result } uses_user_permissions acts_as_commentable uses_comment_extensions acts_as_taggable_on :tags has_paper_trail class_name: 'Version', ignore: [:subscribed_users] has_fields exportable sortable by: ["name ASC", "target_leads DESC", "target_revenue DESC", "leads_count DESC", "revenue DESC", "starts_on DESC", "ends_on DESC", "created_at DESC", "updated_at DESC"], default: "created_at DESC" has_ransackable_associations %w(leads opportunities tags activities emails comments tasks) ransack_can_autocomplete validates_presence_of :name, message: :missing_campaign_name validates_uniqueness_of :name, scope: [:user_id, :deleted_at] validate :start_and_end_dates validate :users_for_shared_access validates :status, inclusion: { in: proc { Setting.unroll(:campaign_status).map { |s| s.last.to_s } } }, allow_blank: true # Default values provided through class methods. #---------------------------------------------------------------------------- def self.per_page 20 end # Attach given attachment to the campaign if it hasn't been attached already. #---------------------------------------------------------------------------- def attach!(attachment) unless send("#{attachment.class.name.downcase}_ids").include?(attachment.id) if attachment.is_a?(Task) send(attachment.class.name.tableize) << attachment else # Leads, Opportunities attachment.update_attribute(:campaign, self) attachment.send("increment_#{attachment.class.name.tableize}_count") [attachment] end end end # Discard given attachment from the campaign. #---------------------------------------------------------------------------- def discard!(attachment) if attachment.is_a?(Task) attachment.update_attribute(:asset, nil) else # Leads, Opportunities attachment.send("decrement_#{attachment.class.name.tableize}_count") attachment.update_attribute(:campaign, nil) end end private # Make sure end date > start date. #---------------------------------------------------------------------------- def start_and_end_dates if (starts_on && ends_on) && (starts_on > ends_on) errors.add(:ends_on, :dates_not_in_sequence) end end # Make sure at least one user has been selected if the campaign is being shared. #---------------------------------------------------------------------------- def users_for_shared_access errors.add(:access, :share_campaign) if self[:access] == "Shared" && !permissions.any? end ActiveSupport.run_load_hooks(:fat_free_crm_campaign, self) end