class PSheetLine < ActiveRecord::Base
  belongs_to :p_customer_sheet
  
  belongs_to :p_document
  
  has_one :p_customer, :through => :p_customer_sheet
  belongs_to :p_product
  belongs_to :p_tank
  
  
  belongs_to :archived_p_product, :class_name => "PProduct"
  
  has_many :p_sheet_line_stocks, :dependent => :destroy
  
  has_many :p_sheet_line_lines, :dependent => :destroy
  accepts_nested_attributes_for :p_sheet_line_lines
  #validates :qte, :presence => true
  #validates :price, :presence => true
  
  validates :ok_qte, :presence => true, :if => :validate_ok?
  validates :ok_price, :presence => true, :if => :validate_ok?
  validates :ok_at, :presence => true, :if => :validate_ok?
  
  validates :p_product, :presence => true
  #validates :p_tank, :presence => true, :if => :validate_tank?
  
  
	scope :oks, -> {where(:shiped => true).order("ok_at DESC")}
  scope :not_oks, -> {where(:shiped => false).order("ok_at DESC")}
	
	scope :between, lambda { |start, stop|
	        after(start).before(stop)
	    }
	
	scope :after, lambda { |date|
	        where("(ok_at >= ?)", date )
	    }
	scope :before, lambda { |date|
	        where("(ok_at <= ?)", date )
	    }
     
  after_save do
    self.p_customer_sheet.save if self.p_customer_sheet
  end 
      
  before_save do 
    self.a_total_cost_ok = self.total_cost_ok
    
    
    if self.bl and self.ok
      self.shiped = true
      self.lock = true
    end
    
    
    
    
  end
  
  def ship_affects
    affecteds = {}
    
    
    
    qte_to_affect = qte
    
    last_qte = nil
    self.p_product.p_qtes.order("qte DESC").each do |p_qte|
      last_qte = p_qte.qte
      
      nbr = 0
      nbr = (qte_to_affect.to_f / p_qte.qte.to_f).floor
      affecteds[last_qte] = nbr if nbr > 0
      
      
      
      
      qte_to_affect = qte_to_affect.modulo(p_qte.qte)
    end
 
    if qte_to_affect > 0
      affecteds[last_qte] = affecteds[last_qte].to_i + 1
    end
    
    r = 0
    
    affecteds.each do |index, value|
      r += value
    end
    return({:affecteds => affecteds, :nbr => r, :reste => qte_to_affect})
  
  
  
  end
  
  def fige
    self.ok_price = self.price
    
    if !self.ok_price
      self.ok_price = self.price
    end
    
    if self.p_product and !self.archived_p_product
      self.archived_p_product = self.p_product.dup
      self.archived_p_product.archived = true
      
    end 
    
    
  end
  
  
  def product_name
    if self.archived_p_product
      self.archived_p_product.name
    elsif self.p_product
      self.p_product.name 
      
    end
    
  end
  
  
  
  def price
    
    
    
    
    if ok_price?
      price = ok_price
    else
      
      if self.p_customer and self.p_customer.p_price_cat
              p_price_cat = self.p_customer.p_price_cat
      else
              p_price_cat = PPriceCat.first
      end
        
        
      
      
      product_degressif = self.p_product.p_degressifs.joins(:p_price_cats).where("nbr <= ?", self.qte).where(:p_price_cats => {:id => p_price_cat.id}).order("nbr DESC").first
      if product_degressif
        price = product_degressif.price.to_f
   
      else
        0.0
      end
    end
    
    return price
    
  end
  
  def qte
    self.p_sheet_line_lines.sum(:qte)
  end
  before_create do
    
    if self.p_customer_sheet
      self.generate_p_sheet_line_lines
    end
    
  end
  
  def generate_p_sheet_line_lines
    self.p_product.p_product_stocks.order("p_size_id ASC, p_color_id ASC").each do |ps|
    
      self.p_sheet_line_lines << PSheetLineLine.new(:p_product_stock_id => ps.id)
    
    end
  end
  
  
  def cost_u_ok
    self.total_cost_ok / self.ok_qte.to_f
  end
  
  def marge_u_ok
    self.marge_ok / self.ok_qte.to_f
  end
  
  def marge_ok
    self.ok_price_tot - self.total_cost_ok
  end
      
  def total_cost_ok
    var = 0.0
    self.p_sheet_line_stocks.each do |p_sheet_line_stock|
      var += p_sheet_line_stock.price_tot_ok
      
    end
    return var
  end
  
  
  def stock_is_ok
    if !self.stock_done
      if self.brut_product_needs_ok.size == self.p_sheet_line_stocks.group(:p_brut_product_id).length
      
        self.stock_done = true
        self.save
      
      end
    end
  end
  
  def update_stock
    if !self.externe and !self.stock_is_ok and self.shiped
      self.brut_product_needs_ok.each do |brut_index, brut_qte|
        p_brut_product = PBrutProduct.find(brut_index)
        qte_restante = brut_qte.to_f
      
        p_product_brut_stocks = PProductBrutStock.where(:p_brut_product_id => p_brut_product.id).where("qte_restant > 0.0").order("ok_at ASC").limit(100)
      
        if p_product_brut_stocks.sum(:qte_restant) >= qte_restante and self.p_sheet_line_stocks.where(:p_brut_product_id => p_brut_product.id).count == 0
      
          i = 0
          while qte_restante > 0.0
            p_product_brut_stock = p_product_brut_stocks[i]
        
            if qte_restante <= p_product_brut_stock.qte_restant
              qte_to_affect = qte_restante
          
            else
              qte_to_affect = p_product_brut_stock.qte_restant
            end
        
            a = self.p_sheet_line_stocks.build(:ok_at => self.ok_at,:ok => true, :p_brut_product_id => p_brut_product.id, :qte_ok => qte_to_affect, :price_ok => p_product_brut_stock.ok_price, :p_product_brut_stock_id => p_product_brut_stock.id)
    
          
            p_product_brut_stock.qte_restant = p_product_brut_stock.qte_restant.to_f - qte_to_affect
            p_product_brut_stock.save
            qte_restante = qte_restante - qte_to_affect
            i += 1
        
          end
      
        end
      
      end
    
      self.save
      self.stock_is_ok
    end
  end
  
  def brut_product_needs
    var = {}
    self.p_product.p_product_brut_products.each do |p_product_brut_product|
      var[p_product_brut_product.p_brut_product_id] = p_product_brut_product.qte.to_f * self.qte.to_f
    end
    return var
  end
  
  def brut_product_needs_ok
    var = {}
    self.p_product.p_product_brut_products.each do |p_product_brut_product|
      var[p_product_brut_product.p_brut_product_id] = p_product_brut_product.qte.to_f * self.ok_qte.to_f
    end
    return var
  end
  
  def generate_bl
    self.p_customer_sheet.generate_bl(self.id)
  end
  
  def validate_tank?
    if self.externe
      false
      self.p_tank = nil
    else
      true
    end
  end
  
  def validate_ok?
    if self.ok
      true
    else
      false
    end
  end
  
  def price_tot
    self.qte.to_f * self.price.to_f
  end 
  
  def tva
    0.2
  end
  
  def price_tot_ttc
    self.price_tot * (self.tva + 1.0)
  end
  
  
  def ok_price_tot
    self.ok_qte.to_f * self.ok_price.to_f
  end 
  
  def ok_price_tot_ttc
    self.ok_price_tot * (self.tva + 1.0)
  end
    
  
  def self.totals(sheet_lines)

    
    return {
      :total => self.total_with_labels(sheet_lines)[:total][:value] ,
      :total_ttc => self.total_with_labels(sheet_lines)[:total_ttc][:value],

    }
  end
  
  
  def self.total_articles(sheet_lines)
    
    total = 0.0
    total_ttc = 0.0

    
    sheet_lines.each do |sheet_line|
      
      total += sheet_line.price_tot
      total_ttc += sheet_line.price_tot_ttc

    end
    
    return {
      :total => total,
      :total_ttc => total_ttc,

    }
  end
  
  
  def self.total_with_labels(sheet_lines, sheet_line_container=nil)
    
    total = 0.0
    total_ttc = 0.0
    r = {}
    
    sheet_lines.each do |sheet_line|
      
      total += sheet_line.price_tot
      total_ttc += sheet_line.price_tot_ttc

    end
    
    r[:total_articles] = {:label =>"Total articles HT",:value => total}
    fdp = 0

    fdp = PSheetLine.frais_de_port(sheet_lines)
    r[:fdp] = {:label =>"Frais de port HT",:value => fdp}
    
    
    total = total +fdp.to_f
    total_ttc = total_ttc + (fdp.to_f*1.2)
    r[:total] = {:label =>"Total HT",:value => total}
    r[:tva] = {:label =>"TVA",:value => total_ttc - total}
    r[:total_ttc] = {:label =>"Total TTC",:value => total_ttc}
    
    
    return r
    
    
  end
  
  
  
  def self.frais_de_port(p_sheet_lines)
    
    if p_sheet_lines[0] and ((p_sheet_lines[0].p_customer_sheet and p_sheet_lines[0].p_customer_sheet.fdp_force_price) or (p_sheet_lines[0].p_document and p_sheet_lines[0].p_document.fdp_force_price))
      if p_sheet_lines[0].p_document
        p_sheet_lines[0].p_document.fdp_force_price
      elsif p_sheet_lines[0].p_customer_sheet
        p_sheet_lines[0].p_customer_sheet.fdp_force_price
      end
      
    else
      if PSheetLine.total_articles(p_sheet_lines)[:total] > PSheetLine.franco_port
        0.0
      else
        PSheetLine.ship_affects(p_sheet_lines) * PSheetLine.carton_price
      
      
      end
    
    end
    
    
    
    
    
    
  end
  
  def self.ship_affects(p_sheet_lines)
    nbr = 0
    p_sheet_lines.all.each do |p_sheet_line|
      nbr += p_sheet_line.ship_affects[:nbr]
    end
    
    return nbr
  end
  
  
  def self.franco_port 
    1000.0
  end
  
  def self.carton_price
    15.0
  end
  
  
  
  def sheet_figed
    if self.p_document and 1
    end
  end
  
end
