# == Schema Information
# Schema version: 51
#
# Table name: transza
#
#  transza_id    :integer         primary key
#  uzytkownik_id :integer         
#  created_at    :timestamp       
#  updated_at    :timestamp       
#

 #
 # This file is part of the Anotatornia suite.
 # 
 # Copyright © 2007, 2008, 2009, 2010 by Instytut Podstaw Informatyki
 # Polskiej Akademii Nauk (IPI PAN; Institute of Computer Science, Polish
 # Academy of Sciences; cf. www.ipipan.waw.pl).  All rights reserved.
 # 
 # This file may be distributed and/or modified under the terms of the
 # GNU General Public License version 3 as published by the Free Software
 # Foundation and appearing in the file COPYING included in the packaging
 # of this file.  (See http://www.gnu.org/licenses/translations.html for
 # unofficial translations.)
 # 
 # A commercial license is available from IPI PAN (contact
 # Michal.Ciesiolka.waw.pl or ipi.waw.pl for more
 # information).  Licensees holding a valid commercial license from IPI
 # PAN may use this file in accordance with that license.
 # 
 # This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
 # THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 # PURPOSE.
 #

require 'ramkowanie'

Uzytkownik.find( :first ) # just to wake it up

class Transza < ActiveRecord::Base

  LICZBA_AKAPITÓW = 2 * AnoVersion.rozmiar_transzy
  # klasa #AnoVersion jest zdefiniowana w~pliku \file{nk8003.rb}.

  belongs_to :uzytkownik
  
  has_many :akapit_transzy, :order => "status desc, akapit_transzy_id"  

  has_many :akapity_transzy_niezatwierdzone, 
  :class_name => "AkapitTranszy",
  :order => "status desc, akapit_transzy_id", 
  :conditions => [" status < ? ", AkapitTranszy::STATI[:zatwierdzony]]

  has_many :akapity_transzy_zatwierdzone, 
  :class_name => "AkapitTranszy",
  :order => "status desc, akapit_transzy_id", 
  :conditions => [" status = ? ", AkapitTranszy::STATI[:zatwierdzony]]
  
  has_many :akapity_transzy_rozbiezne, 
  :class_name => "AkapitTranszy",
  :order => "status desc, akapit_transzy_id", 
  :conditions => [" status between ? and ? ", 
                  AkapitTranszy::STATI[:zatwierdzony]+1,
                  AkapitTranszy::STATI[:zweryfikowany]-1]

  has_many :akapity_transzy_zamkniete, 
  :class_name => "AkapitTranszy",
  :order => "status desc, odrzucony, akapit_transzy_id", 
  :conditions => ["status >= ?", AkapitTranszy::STATI[:zweryfikowany]]

  has_one :prosby_anotatorek, :as => :dotyczy

  if DlaEli.x
    MAX_TRANSZ = 5
  else MAX_TRANSZ = 25 # podwyższone z~5 2009/7/4 (\#162)
  end


  def validate
    # musimy sprawdzać, że użytkownik nie ma dwa razy takiej samej transzy!!!
    # np. ustanawiając numerację transz od 0, 
    # że (nr_nowej div 2) not in select (nry_przydzielonych div 2)
  end

  def opis
    ile_zaa = Proc.new { |*status_sym|
      AkapitTranszy.ile_zaanotowanych({:transza_id => self.id}, *status_sym )
    }
    zakończonych = ile_zaa.call( :zakończony )
    oczekujących = ile_zaa.call( :oczekujące )
    anotaśnych = ile_zaa.call( :anotaśne, :to_ary )
    if anotaśnych.max == 0
      do_anotacji = "nic do anotacji"
    else
      do_anotacji = " #{anotaśnych.inspect} do anotacji"
    end

    podsądnych = ile_zaa.call( :podsądny, :to_ary )
    podsądnych =
      if podsądnych.max == 0
        ''  
      else
        " i #{podsądnych.inspect} pod sądem"
      end

    "#{self.transza_id}" + 
      " (#{self.ile_akapitów} ak., w tym #{zakończonych} zak. i #{oczekujących} ocz. — #{do_anotacji}#{podsądnych})"
  end # of #opis

  alias :opis_nohtml :opis
    
  def ile_akapitów # myślę, że zadziała dużo szybciej i~prościej niż #{self.akapit_transzy.size}.
    self.class.find_by_sql( 
                           [ "select count(*) as ile from akapit_transzy where transza_id=?", 
                             self.id ] )[0].ile.to_i
  end
  
  def sa_jakies_rozbieznosci?( over_symb )
    saro=AkapitTranszy.find_by_sql([
                                    "select count(*) as ile from akapit_transzy " +
                                    " where transza_id = ? and status between ? and ? ",
                                    self.transza_id, 
                                    AkapitTranszy::STATI[:zatwierdzony]+1,
                                    AkapitTranszy::STATI[over_symb]-1,
                                   ])[0].ile.to_i
    if saro==0 : return nil ; else return saro end
  end


  def do_poprawki?
    sa_jakies_rozbieznosci?( :po_konfrontacji2 )
  end


  def sa_rozbiezne?
    sa_jakies_rozbieznosci?( :zweryfikowany )
  end


  def self.lista_transz( meth_symb = :wsze_transze )
    # zwraca tablicę par #{[ \<anotatorka>, [\<jej transze (np. otwarte)>]]}
    anotatores = Uzytkownik.find(:all, 
                           :conditions => {:rola_id => Rola.rid( :anotator )},
                           :order => :login)
    if meth_symb == :wsze_transze
      tros = anotatores.collect{ |anor|  [anor, 
                                   anor.transze_otwarte + ( anor.transza - anor.transze_otwarte )] }
    else
      tros = anotatores.collect{ |anor|  [anor, anor.send(meth_symb)] }
    end
    return tros
  end # of #{self.lista_transz}.

  
  def self.wsze_otwarte 
    self.lista_transz( :transze_otwarte )
  end

  def self.wsze
    self.lista_transz
  end

  HOW_MANY_RECENT = 40

  def self.recent_closed
    # we'll return the list of #how_many most recently closed transzas.
    self.find_by_sql ( " 
select x.*, login from (
select transza.*, 
max( max(a.updated_at), max( s.updated_at )) as true_updated_at 
from transza inner join akapit_transzy a using( transza_id ) 
inner join statusy s using( akapit_transzy_id ) 
where (select count(*) from akapit_transzy psi where psi.transza_id=transza.transza_id)=
(select count(*) from akapit_transzy ksi where ksi.transza_id=transza.transza_id 
and ksi.status>=16 )
group by transza.transza_id 
order by true_updated_at desc limit #{HOW_MANY_RECENT}) as x 
inner join uzytkownik using( uzytkownik_id )
order by login, true_updated_at desc;
"
)
  end



  def self.zrob_transze( pełne=nil )
    idæ_nullæ = "select akapit_id from akapit a left outer join akapit_transzy at using( akapit_id ) " +
      " where  akapit_transzy_id is null "
    if self.find_by_sql( " select 1 as jeden where exists ( #{idæ_nullæ} ) " )[0]
      if pełne
        inu = self.find_by_sql( idæ_nullæ ).collect{ |a| a.akapit_id }
        idæ_nullæ = inu[ 0, [inu.size - inu.size % LICZBA_AKAPITÓW, 0].max  ]
        cond = { :akapit_id => idæ_nullæ }
      else
        cond = " akapit_id in ( #{idæ_nullæ} ) " 
      end
      a = Akapit.find( :all, :conditions => cond ) # ostatni warunek jest prawie na pewno redundantny, tzn. ograniczenie »od–do«.
      as200=a.size/LICZBA_AKAPITÓW+1
      as200.times{ |i|
        akaa = a[i*LICZBA_AKAPITÓW, LICZBA_AKAPITÓW]
        pocwiartuj( akaa )
      }
      
    end# of main #unless

    self.unnull_akat_bliźniaki
    
  end# of #{self.zrob_transze}.
  
  private

  def self.zrobakapitytranszy( akaa_n )
    if akaa_n[0]
      # 2009/05/22,  \#116 na Tracu: wersja 8005 miała transze puste (bo w~\rz1 turze wlano 17 akapitów.
      tra = self.create
      akaa_n.each {|aka| tra.akapit_transzy.create( :akapit_id => aka.akapit_id ) }
    end
  end


  def self.pocwiartuj( akaa )
    # np. dla tablicy 200 akapitów  dzielimy je po 50 
    # i łączymy 0: I i II, 1: III i IV, 2: I i III, 3: II i IV
    cwierc=akaa.length/4
    akaa= [
            akaa[0,cwierc*2],
            akaa[cwierc*2, cwierc*2+3],
            akaa[0, cwierc] + akaa[cwierc*2, cwierc],
            akaa[cwierc, cwierc] + akaa[cwierc*3, cwierc+3]
            ]

    self.zrobakapitytranszy( akaa[0] )
    self.zrobakapitytranszy( akaa[1] )
    self.zrobakapitytranszy( akaa[2] )
    self.zrobakapitytranszy( akaa[3] )
  end# of #{self.pocwiartuj}.

  ##  zrob_transze
  ##  Statusy.find( :first )

end # of class.

### Local Variables: 
### mode: ruby
### End:
