<commit_before>class ProgramSession < ApplicationRecord
  LIVE = 'live' # confirmed accepted
  DRAFT = 'draft' # created by organizer, not ready to be published (live)
  UNCONFIRMED_ACCEPTED = 'unconfirmed accepted' # accepted, to be confirmed by speaker
  UNCONFIRMED_WAITLISTED = 'unconfirmed waitlisted'
  CONFIRMED_WAITLISTED = 'confirmed waitlisted'
  DECLINED = 'declined'

  STATES = [
    LIVE,
    DRAFT,
    UNCONFIRMED_ACCEPTED,
    UNCONFIRMED_WAITLISTED,
    CONFIRMED_WAITLISTED,
    DECLINED
  ]

  STATE_GROUPS = {
    LIVE => "program",
    DRAFT => "program",
    UNCONFIRMED_ACCEPTED => "program",
    UNCONFIRMED_WAITLISTED => "waitlist",
    CONFIRMED_WAITLISTED => "waitlist",
    DECLINED => "declined"
  }

  PROMOTIONS = {
    DRAFT => LIVE,
    UNCONFIRMED_WAITLISTED => UNCONFIRMED_ACCEPTED,
    CONFIRMED_WAITLISTED => LIVE
  }

  CONFIRMATIONS = {
    UNCONFIRMED_WAITLISTED => CONFIRMED_WAITLISTED,
    UNCONFIRMED_ACCEPTED => LIVE
  }

  belongs_to :event
  belongs_to :proposal
  belongs_to :track
  belongs_to :session_format
  has_one :time_slot, dependent: :nullify
  has_many :speakers, -> { order(:created_at)}

  accepts_nested_attributes_for :speakers
  accepts_nested_attributes_for :proposal

  validates :event, :session_format, :title, :state, presence: true

  validates_inclusion_of :state, in: STATES

  serialize :info, Hash

  after_destroy :destroy_speakers

  scope :unscheduled, -> do
    where(state: LIVE).where.not(id: TimeSlot.pluck(:program_session_id))
  end
  scope :sorted_by_title, -> { order(:title)}
  scope :live, -> { where(state: LIVE) }
  scope :draft, -> { where(state: DRAFT) }
  scope :waitlisted, -> { where(state: [CONFIRMED_WAITLISTED, UNCONFIRMED_WAITLISTED]) }
  scope :program, -> { where(state: [LIVE, DRAFT, UNCONFIRMED_ACCEPTED]) }
  scope :declined, -> { where(state: DECLINED) }
  scope :without_proposal, -> { where(proposal: nil) }
  scope :in_track, ->(track) do
    track = nil if track.try(:strip).blank?
    where(track: track)
  end
  scope :emails, -> { joins(:speakers).pluck(:speaker_email).uniq }

  scope :in_session_format, ->(session_format) do
    where(session_format_id: session_format.id)
  end

  def self.create_from_proposal(proposal)
    self.transaction do
      ps = ProgramSession.create!(event_id: proposal.event_id,
                                  proposal_id: proposal.id,
                                  title: proposal.title,
                                  abstract: proposal.abstract,
                                  track_id: proposal.track_id,
                                  session_format_id: proposal.session_format_id,
                                  state: proposal.waitlisted? ? UNCONFIRMED_WAITLISTED : UNCONFIRMED_ACCEPTED
      )

      #attach proposal speakers to new program session
      ps.speakers << proposal.speakers
      ps.speakers.each do |speaker|
        (speaker.speaker_name = speaker.user.name) if speaker.speaker_name.blank?
        (speaker.speaker_email = speaker.user.email) if speaker.speaker_email.blank?
        (speaker.bio = speaker.user.bio) if speaker.bio.blank?
        speaker.save!<commit_msg>Our program needs to get the current title and abstract from proposal<commit_after>class ProgramSession < ApplicationRecord
  LIVE = 'live' # confirmed accepted
  DRAFT = 'draft' # created by organizer, not ready to be published (live)
  UNCONFIRMED_ACCEPTED = 'unconfirmed accepted' # accepted, to be confirmed by speaker
  UNCONFIRMED_WAITLISTED = 'unconfirmed waitlisted'
  CONFIRMED_WAITLISTED = 'confirmed waitlisted'
  DECLINED = 'declined'

  STATES = [
    LIVE,
    DRAFT,
    UNCONFIRMED_ACCEPTED,
    UNCONFIRMED_WAITLISTED,
    CONFIRMED_WAITLISTED,
    DECLINED
  ]

  STATE_GROUPS = {
    LIVE => "program",
    DRAFT => "program",
    UNCONFIRMED_ACCEPTED => "program",
    UNCONFIRMED_WAITLISTED => "waitlist",
    CONFIRMED_WAITLISTED => "waitlist",
    DECLINED => "declined"
  }

  PROMOTIONS = {
    DRAFT => LIVE,
    UNCONFIRMED_WAITLISTED => UNCONFIRMED_ACCEPTED,
    CONFIRMED_WAITLISTED => LIVE
  }

  CONFIRMATIONS = {
    UNCONFIRMED_WAITLISTED => CONFIRMED_WAITLISTED,
    UNCONFIRMED_ACCEPTED => LIVE
  }

  belongs_to :event
  belongs_to :proposal
  belongs_to :track
  belongs_to :session_format
  has_one :time_slot, dependent: :nullify
  has_many :speakers, -> { order(:created_at)}

  accepts_nested_attributes_for :speakers
  accepts_nested_attributes_for :proposal

  validates :event, :session_format, :title, :state, presence: true

  validates_inclusion_of :state, in: STATES

  serialize :info, Hash

  after_destroy :destroy_speakers

  scope :unscheduled, -> do
    where(state: LIVE).where.not(id: TimeSlot.pluck(:program_session_id))
  end
  scope :sorted_by_title, -> { order(:title)}
  scope :live, -> { where(state: LIVE) }
  scope :draft, -> { where(state: DRAFT) }
  scope :waitlisted, -> { where(state: [CONFIRMED_WAITLISTED, UNCONFIRMED_WAITLISTED]) }
  scope :program, -> { where(state: [LIVE, DRAFT, UNCONFIRMED_ACCEPTED]) }
  scope :declined, -> { where(state: DECLINED) }
  scope :without_proposal, -> { where(proposal: nil) }
  scope :in_track, ->(track) do
    track = nil if track.try(:strip).blank?
    where(track: track)
  end
  scope :emails, -> { joins(:speakers).pluck(:speaker_email).uniq }

  scope :in_session_format, ->(session_format) do
    where(session_format_id: session_format.id)
  end

  def title
    proposal&.title || super
  end

  def abstract
    proposal&.abstract || super
  end

  def self.create_from_proposal(proposal)
    self.transaction do
      ps = ProgramSession.create!(event_id: proposal.event_id,
                                  proposal_id: proposal.id,
                                  title: proposal.title,
                                  abstract: proposal.abstract,
                                  track_id: proposal.track_id,
                                  session_format_id: proposal.session_format_id,
                                  state: proposal.waitlisted? ? UNCONFIRMED_WAITLISTED : UNCONFIRMED_ACCEPTED
      )

      #attach proposal speakers to new program session
      ps.speakers << proposal.speakers
      ps.speakers.each do |speaker|
        (speaker.speaker_name = speaker.user.name) if speaker.speaker_name.blank?
        (speaker.speaker_email = speaker.user.email) if speaker.speaker_email.blank?
        (speaker.bio = speaker.user.bio) if speaker.bio.blank?
        speaker.save!
{'fraction_non_alphanumeric': 0.09944410129709698, 'fraction_numerical': 0.0, 'mean_word_length': 3.0735849056603772, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 49, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 12, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7434210', 'n_tokens_mistral': 2188, 'n_tokens_neox': 2101, 'n_words': 432}