app/models/entities/opportunity.rb in fat_free_crm-0.13.6 vs app/models/entities/opportunity.rb in fat_free_crm-0.14.0

- old
+ new

@@ -24,19 +24,19 @@ # updated_at :datetime # background_info :string(255) # class Opportunity < ActiveRecord::Base - belongs_to :user - belongs_to :campaign - belongs_to :assignee, :class_name => "User", :foreign_key => :assigned_to - has_one :account_opportunity, :dependent => :destroy - has_one :account, :through => :account_opportunity - has_many :contact_opportunities, :dependent => :destroy - has_many :contacts, :through => :contact_opportunities, :uniq => true, :order => "contacts.id DESC" - has_many :tasks, :as => :asset, :dependent => :destroy#, :order => 'created_at DESC' - has_many :emails, :as => :mediator + belongs_to :user + belongs_to :campaign + belongs_to :assignee, class_name: "User", foreign_key: :assigned_to + has_one :account_opportunity, dependent: :destroy + has_one :account, through: :account_opportunity + has_many :contact_opportunities, dependent: :destroy + has_many :contacts, -> { order("contacts.id DESC").distinct }, through: :contact_opportunities + has_many :tasks, as: :asset, dependent: :destroy # , :order => 'created_at DESC' + has_many :emails, as: :mediator serialize :subscribed_users, Set scope :state, ->(filters) { where('stage IN (?)' + (filters.delete('other') ? ' OR stage IS NULL' : ''), filters) @@ -50,49 +50,52 @@ scope :unassigned, -> { where("opportunities.assigned_to IS NULL") } # Search by name OR id scope :text_search, ->(query) { if query =~ /\A\d+\z/ - where('upper(name) LIKE upper(:name) OR opportunities.id = :id', :name => "%#{query}%", :id => query) + where('upper(name) LIKE upper(:name) OR opportunities.id = :id', name: "%#{query}%", id: query) else search('name_cont' => query).result end } scope :visible_on_dashboard, ->(user) { # Show opportunities which either belong to the user and are unassigned, or are assigned to the user and haven't been closed (won/lost) - where('(user_id = :user_id AND assigned_to IS NULL) OR assigned_to = :user_id', :user_id => user.id).where("opportunities.stage != 'won'").where("opportunities.stage != 'lost'") + where('(user_id = :user_id AND assigned_to IS NULL) OR assigned_to = :user_id', user_id: user.id).where("opportunities.stage != 'won'").where("opportunities.stage != 'lost'") } scope :by_closes_on, -> { order(:closes_on) } scope :by_amount, -> { order('opportunities.amount DESC') } uses_user_permissions acts_as_commentable uses_comment_extensions acts_as_taggable_on :tags - has_paper_trail :ignore => [ :subscribed_users ] + has_paper_trail class_name: 'Version', ignore: [:subscribed_users] has_fields exportable - sortable :by => [ "name ASC", "amount DESC", "amount*probability DESC", "probability DESC", "closes_on ASC", "created_at DESC", "updated_at DESC" ], :default => "created_at DESC" + sortable by: ["name ASC", "amount DESC", "amount*probability DESC", "probability DESC", "closes_on ASC", "created_at DESC", "updated_at DESC"], default: "created_at DESC" has_ransackable_associations %w(account contacts tags campaign activities emails comments) ransack_can_autocomplete - validates :stage, :inclusion => { :in => Proc.new { Setting.unroll(:opportunity_stage).map{|s| s.last.to_s } } } - - validates_presence_of :name, :message => :missing_opportunity_name - validates_numericality_of [ :probability, :amount, :discount ], :allow_nil => true + validates_presence_of :name, message: :missing_opportunity_name + validates_numericality_of [:probability, :amount, :discount], allow_nil: true validate :users_for_shared_access + validates :stage, inclusion: { in: proc { Setting.unroll(:opportunity_stage).map { |s| s.last.to_s } } }, allow_blank: true - after_create :increment_opportunities_count + after_create :increment_opportunities_count after_destroy :decrement_opportunities_count # Default values provided through class methods. #---------------------------------------------------------------------------- - def self.per_page ; 20 ; end - def self.default_stage; Setting[:opportunity_default_stage].try(:to_s) || 'prospecting'; end + def self.per_page + 20 + end + def self.default_stage + Setting[:opportunity_default_stage].try(:to_s) || 'prospecting' + end #---------------------------------------------------------------------------- def weighted_amount ((amount || 0) - (discount || 0)) * (probability || 0) / 100.0 end @@ -101,51 +104,47 @@ #---------------------------------------------------------------------------- def save_with_account_and_permissions(params) # Quick sanitization, makes sure Account will not search for blank id. params[:account].delete(:id) if params[:account][:id].blank? account = Account.create_or_select_for(self, params[:account]) - self.account_opportunity = AccountOpportunity.new(:account => account, :opportunity => self) unless account.id.blank? + self.account_opportunity = AccountOpportunity.new(account: account, opportunity: self) unless account.id.blank? self.account = account self.campaign = Campaign.find(params[:campaign]) unless params[:campaign].blank? - result = self.save - self.contacts << Contact.find(params[:contact]) unless params[:contact].blank? + result = save + contacts << Contact.find(params[:contact]) unless params[:contact].blank? result end # Backend handler for [Update Opportunity] form (see opportunity/update). #---------------------------------------------------------------------------- def update_with_account_and_permissions(params) if params[:account] && (params[:account][:id] == "" || params[:account][:name] == "") self.account = nil # Opportunity is not associated with the account anymore. elsif params[:account] - account = Account.create_or_select_for(self, params[:account]) - if self.account != account and account.id.present? - self.account_opportunity = AccountOpportunity.new(:account => account, :opportunity => self) - end + self.account = Account.create_or_select_for(self, params[:account]) end - self.reload # Must set access before user_ids, because user_ids= method depends on access value. self.access = params[:opportunity][:access] if params[:opportunity][:access] self.attributes = params[:opportunity] - self.save + save end # Attach given attachment to the opportunity if it hasn't been attached already. #---------------------------------------------------------------------------- def attach!(attachment) - unless self.send("#{attachment.class.name.downcase}_ids").include?(attachment.id) - self.send(attachment.class.name.tableize) << attachment + unless send("#{attachment.class.name.downcase}_ids").include?(attachment.id) + send(attachment.class.name.tableize) << attachment end end # Discard given attachment from the opportunity. #---------------------------------------------------------------------------- def discard!(attachment) if attachment.is_a?(Task) attachment.update_attribute(:asset, nil) else # Contacts - self.send(attachment.class.name.tableize).delete(attachment) + send(attachment.class.name.tableize).delete(attachment) end end # Class methods. #---------------------------------------------------------------------------- @@ -153,37 +152,38 @@ opportunity = Opportunity.new(params) # Save the opportunity if its name was specified and account has no errors. if opportunity.name? && account.errors.empty? # Note: opportunity.account = account doesn't seem to work here. - opportunity.account_opportunity = AccountOpportunity.new(:account => account, :opportunity => opportunity) unless account.id.blank? + opportunity.account_opportunity = AccountOpportunity.new(account: account, opportunity: opportunity) unless account.id.blank? if opportunity.access != "Lead" || model.nil? opportunity.save else opportunity.save_with_model_permissions(model) end end opportunity end private + # Make sure at least one user has been selected if the contact is being shared. #---------------------------------------------------------------------------- def users_for_shared_access - errors.add(:access, :share_opportunity) if self[:access] == "Shared" && !self.permissions.any? + errors.add(:access, :share_opportunity) if self[:access] == "Shared" && !permissions.any? end #---------------------------------------------------------------------------- def increment_opportunities_count - if self.campaign_id - Campaign.increment_counter(:opportunities_count, self.campaign_id) + if campaign_id + Campaign.increment_counter(:opportunities_count, campaign_id) end end #---------------------------------------------------------------------------- def decrement_opportunities_count - if self.campaign_id - Campaign.decrement_counter(:opportunities_count, self.campaign_id) + if campaign_id + Campaign.decrement_counter(:opportunities_count, campaign_id) end end ActiveSupport.run_load_hooks(:fat_free_crm_opportunity, self) end