class PSheetLine < ApplicationRecord
  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
  
  has_one :particular_send, :through => :p_customer_sheet
  
  has_many :p_sheet_line_stocks, :dependent => :destroy
  
  has_many :p_ship_tour_truck_sheet_lines, :dependent => :destroy
  
  
  validates :custom_title, :presence => true, :if => :custom?
  
  validates :qte, :presence => true, :if => :not_validated?
  validates :price, :presence => true, :if => :not_validated?
  
  validates :ok_qte, :presence => true, :if => :validate_ok?
  validates :ok_price, :presence => true, :if => :validate_ok?
  validates :ok_at, :presence => true, :if => :validate_ok_at?
  
  validates :p_product, :presence => true, :if => :product_needed?
  #validates :p_tank, :presence => true, :if => :validate_tank?
  
  has_many :p_payments
  
	scope :oks, -> {where("(shiped = 1 or (shiped = 0 and cancel = 1))").order("ok_at DESC")}
  scope :not_oks, -> {where("(shiped = 0 and cancel = 0)").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 )
	    }
      
  def validate_ok_at?
    if self.element_label != "Avoir" and self.validate_ok?
      true
    else
      false
    end
  end
      
  def product_needed?
    if self.custom
      false
    else
      true
    end
  end
   
   
  def not_validated?
    if !self.price or !self.qte
      false
    else
      true
    end
   
  end
  
  def self.valid_sort

    ["qte", "particulars.cp", "particulars.city", "particulars.organisation, particulars.name, particulars.firstname", "p_products.name"]

  end
  
  def to_ship(p_ship_tour_truck)
    self.lock = true
  
    self.save
  
    self.generate_bl(p_ship_tour_truck.id)
    self.bl = true
    self.save
  
    self.p_customer_sheet.state = "livraison-en-cours"
    self.p_customer_sheet.save
  end
   
    
  after_save do
    self.p_customer_sheet.save if self.p_customer_sheet
    self.p_document.save if self.p_document
    
  end 
  
  
  before_validation do

    if self.custom
      self.no_stock = true
      self.p_product_id = nil
    end
    
    if self.element_label == "Avoir"
      errors.add(:ok_price, "Vous devez indiquer un prix") if !self.ok_price?
      errors.add(:ok_qte, "Vous devez indiquer une quantité") if !self.ok_qte?
      errors.add(:ok_qte, "La quantité doit être négative") if self.ok_qte.to_f > 0
    
    end
    
    if !self.imported
      self.price_tot = (self.qte.to_f * self.price.to_f).round(2) 
      
      
    end
    
    
    if !self.imported 
      self.ok_price_tot = (self.ok_qte.to_f * self.ok_price.to_f).round(2)
      
      
    end
    
    set_ttc()
  
    
    
  end
  
  def set_ttc
    if !self.arrondi or !self.ok_price_tot_ttc
      r = (self.price_tot * (self.tva + 1.0))
      self.price_tot_ttc = r.round(2) 
  
    
      r = (self.ok_price_tot * (self.tva + 1.0))
      self.ok_price_tot_ttc =  r.round(2) 
    end
  end
      
  before_save do 
    self.a_total_cost_ok = self.total_cost_ok if !self.imported
    
    
    if self.bl and self.ok
      self.shiped = true
      self.lock = true
    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  and !self.custom and !self.no_stock
      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("externe = 0").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(p_ship_tour_truck_id = nil)
    self.p_customer_sheet.generate_bl(self.id, p_ship_tour_truck_id)
  end
  
  def ungenerate_bl
    self.p_customer_sheet.p_documents.where(:p_document_type_id => 5, :p_sheet_line_id => self.id).destroy_all
  end
  
  def validate_tank?
    if self.externe or self.custom or self.no_stock
      false
      self.p_tank = nil
    else
      true
    end
  end
  
  def validate_ok?
    if self.ok
      true
    else
      false
    end
  end
  
  
  
  def tva
    if self.p_document and self.p_document.created_at
      t = self.p_document.created_at
    elsif self.p_customer_sheet and self.p_customer_sheet.created_at
      t = self.p_customer_sheet.created_at
    else
      t = Time.now
    end
    t = t.beginning_of_day
    
    if t > Time.parse("2014-01-01 14:00:00").beginning_of_day
      0.2
    else
      0.196
    end
    
  end
  
  def ok_price_ttc
    (ok_price+(ok_price * tva)).round(5)
  end
  
  def price_ttc
    (price+(price * tva)).round(5)
  end
  
    
  
  def self.totals(sheet_lines)
    
    total = 0.0
    total_ttc = 0.0
    ok_total = 0.0
    ok_total_ttc = 0.0
    
    sheet_lines.each do |sheet_line|
      
      total += sheet_line.price_tot
      total_ttc += sheet_line.price_tot_ttc
      ok_total += sheet_line.ok_price_tot
      ok_total_ttc += sheet_line.ok_price_tot_ttc
    end
    
    return {
      :total => total,
      :total_ttc => total_ttc,
      :ok_total => ok_total,
      :ok_total_ttc => ok_total_ttc
    }
  end
  
  def decrement_stock
    if self.shiped
      self.p_sheet_line_stocks.each do |p_sheet_line_stock|
        new_p_sheet_line_stock = p_sheet_line_stock.dup
        new_p_sheet_line_stock.qte_ok = (new_p_sheet_line_stock.qte_ok * -1)
        new_p_sheet_line_stock.price_ok = (new_p_sheet_line_stock.price_ok)
        new_p_sheet_line_stock.decr = true
        new_p_sheet_line_stock.save
        new_p_sheet_line_stock.p_product_brut_stock.qte_restant = new_p_sheet_line_stock.p_product_brut_stock.ok_qte.to_f - new_p_sheet_line_stock.p_product_brut_stock.qte_used_calc
        new_p_sheet_line_stock.p_product_brut_stock.save
        self.save
      end
      
      self.stock_done = true
      self.decr = true
      self.save
      self.p_customer_sheet.save
      
    end
  end
  
end
