|
|
|
class ProjectPackage < ActiveRecord::Base
|
|
|
|
include AASM
|
|
|
|
|
|
|
|
acts_as_attachable
|
|
|
|
|
|
|
|
CATEGORY_VALUES = %w(front backend mobile database cloud_compute_and_big_data devops_and_test ai other)
|
|
|
|
|
|
|
|
attr_accessible :title, :content, :category, :deadline_at, :contact_name, :contact_phone, :min_price, :max_price
|
|
|
|
|
|
|
|
belongs_to :creator, class_name: 'User'
|
|
|
|
|
|
|
|
has_many :project_package_applies, dependent: :destroy
|
|
|
|
has_one :process_project_package_apply, conditions: { status: :pending }, class_name: 'ProjectPackageApply'
|
|
|
|
|
|
|
|
has_many :bidding_users, dependent: :delete_all
|
|
|
|
has_many :win_bidding_users, conditions: { status: :bidding_won }, class_name: 'BiddingUser'
|
|
|
|
has_many :lose_bidding_users, conditions: { status: :bidding_lost }, class_name: 'BiddingUser'
|
|
|
|
|
|
|
|
has_many :attachments, as: :container, dependent: :destroy
|
|
|
|
|
|
|
|
validates :category, presence: true, inclusion: { in: CATEGORY_VALUES }
|
|
|
|
validates :title, presence: true, length: { maximum: 60 }
|
|
|
|
validates :content, presence: true
|
|
|
|
validates :deadline_at, presence: true
|
|
|
|
validates :contact_name, presence: true, length: { maximum: 20 }
|
|
|
|
validates :contact_phone, presence: true, format: { with: /1\d{10}/ }
|
|
|
|
validates :min_price, numericality: { greater_than: 0 }
|
|
|
|
validates :max_price, numericality: { greater_than: ->(obj){ obj.min_price } }, allow_blank: true
|
|
|
|
|
|
|
|
aasm(:status) do
|
|
|
|
state :pending, initiali: true
|
|
|
|
state :applying
|
|
|
|
state :refused
|
|
|
|
state :published
|
|
|
|
state :bidding_ended
|
|
|
|
state :bidding_finished
|
|
|
|
|
|
|
|
event :apply do
|
|
|
|
transitions from: [:pending, :refused], to: :applying
|
|
|
|
end
|
|
|
|
|
|
|
|
event :refuse do
|
|
|
|
transitions from: :applying, to: :refused
|
|
|
|
end
|
|
|
|
|
|
|
|
event :publish do
|
|
|
|
transitions from: :applying, to: :published
|
|
|
|
end
|
|
|
|
|
|
|
|
event :end_bidding do
|
|
|
|
transitions from: :published, to: :bidding_ended
|
|
|
|
end
|
|
|
|
|
|
|
|
event :finish_bidding do
|
|
|
|
transitions from: [:bidding_ended], to: :bidding_finished
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def visitable?
|
|
|
|
!editable?
|
|
|
|
end
|
|
|
|
|
|
|
|
def editable?
|
|
|
|
pending? || applying? || refused?
|
|
|
|
end
|
|
|
|
|
|
|
|
def deletable?
|
|
|
|
pending? || refused?
|
|
|
|
end
|
|
|
|
|
|
|
|
def bidding_end?
|
|
|
|
flag = deadline_at < Time.now
|
|
|
|
end_bidding! if flag && can_end_bidding?
|
|
|
|
flag
|
|
|
|
end
|
|
|
|
|
|
|
|
def can_bidding?(user)
|
|
|
|
published? && !bidding_end? && !bidding_users.exists?(user_id: user.id)
|
|
|
|
end
|
|
|
|
|
|
|
|
def increment_visit_count!
|
|
|
|
ProjectPackage.connection.execute("update project_packages set visit_count = COALESCE(visit_count, 0) + 1 where id = #{id}")
|
|
|
|
end
|
|
|
|
|
|
|
|
def category_text
|
|
|
|
I18n.t("project_package.category.#{category}")
|
|
|
|
end
|
|
|
|
end
|