class PriceDocument < ApplicationRecord
  belongs_to :p_customer
  belongs_to :price_document_type
  validates :price_document_type_id, :presence => true
  belongs_to :p_commercial
  belongs_to :p_devise
  belongs_to :p_payment_type


  has_one :p_compta_element, :dependent => :destroy, :as => :element

  belongs_to :p_fournisseur

  has_one :price_line_block, :as => :price_lineable

  accepts_nested_attributes_for :price_line_block

  belongs_to :ref_element, :polymorphic => true

  has_many :p_payment_documents, :dependent => :destroy
  has_many :p_payments, :through => :p_payment_documents
  has_many :line_stocks, :as => :stockable


  has_many :avoir_p_payment_documents, :dependent => :destroy, :foreign_key => :avoir_id, :class_name => "PPaymentDocument"
  accepts_nested_attributes_for :avoir_p_payment_documents, allow_destroy: true

  PURCHASES = ["Demande prix", "Commande achat", "Facture d'achat"]
  SALES = ["Bon de commande", "Devis", "Bon de livraison", "Facture", "Avoir"]
  # AVANCEMENT = ["0%", "10%", "20%", "30%", "40%", "50%", "60%", "70%", "80%", "90%", "100%"]
  AVANCEMENT = ["0%", "25%", "50%", "75%", "100"]

  validates :public_fournisseur_name, :presence => true, :if => :public_fournisseur_name_needed?

  def public_fournisseur_name_needed?
    if self.label == "Réponse fournisseur"
      true
    else
      false
    end
  end

  has_many :stat_lines
  
  def cancel_stocks
    #Fonction Admin
    self.price_line_block.cost_ok = false
    self.price_line_block.stock_ok = false
    
    self.line_stocks.each do |ls|
      ls.destroy
    end   
    
    self.save 
    
    
    
  end
  

  def generate_stat_lines
    self.stat_lines.destroy_all

    if self.label == "Facture" or self.label == "Avoir"
      if self.price_line_block


        self.price_line_block.price_lines.all.each do |pl|

          st = self.stat_lines.new(:price_line_block_id => self.price_line_block.id, :price_document_number => self.d_number)
          st.price_line_id = pl.id
          st.date = self.date
          st.title = "Ligne produit"
          st.price_u_ht = pl.price_u_ht
          st.price_u_tva = pl.price_u_tva
          st.price_u_ttc = pl.price_u_ttc
          st.qte = 1
          st.tot_line_ht = pl.tot_line_ht
          st.tot_line_tva = pl.tot_line_tva
          st.tot_line_ttc = pl.tot_line_ttc

          st.tot_discount_ht = pl.tot_discount_ht
          st.tot_discount_tva = pl.tot_discount_tva
          st.tot_discount_ttc = pl.tot_discount_ttc

          st.tot_amount_ht = pl.tot_amount_ht
          st.tot_amount_tva = pl.tot_amount_tva
          st.tot_amount_ttc = pl.tot_amount_ttc


          st.cost_ht = pl.cost_ht
          st.cost_u_ht = pl.cost_u_ht
          st.cost_u_w_ht = (pl.weight_tot.to_f != 0.0 ? (pl.cost_u_ht / pl.weight_tot.to_f) : 0.0)
          st.marge_ht = pl.marge_ht
          st.marge_u_ht = pl.marge_u_ht
          st.marge_u_w_ht = (pl.weight_tot.to_f != 0.0 ? (pl.marge_ht.to_f / pl.weight_tot.to_f) : 0.0)
          st.weight_u = pl.weight_u
          st.weight_tot = pl.weight_tot

          if pl.p_product_ref
            st.p_product_ref = pl.p_product_ref

            if pl.p_product_ref.p_product
              st.p_product = pl.p_product_ref.p_product
              st.product_name = pl.p_product_ref.p_product.name
              st.product_code = pl.p_product_ref.p_product.code
              st.title = st.product_code.to_s+" - "+st.product_name.to_s

              if pl.p_product_ref.p_product.p_product_cat
                st.p_product_cat = pl.p_product_ref.p_product.p_product_cat
                st.p_product_cat_name = pl.p_product_ref.p_product.p_product_cat.name

                

              end

              if pl.p_product_ref.p_product.s_brand
                st.s_brand_id = pl.p_product_ref.p_product.s_brand.id
                st.s_brand_name = pl.p_product_ref.p_product.s_brand.name
              end

            end


          end


          if self.p_customer
            st.p_customer = self.p_customer
            st.p_customer_name = self.p_customer.show_name
            st.p_customer_code = self.p_customer.code
          end

          if self.p_commercial
            st.p_commercial = self.p_commercial
            st.p_commercial_name = self.p_commercial.long_name
            st.p_commercial_code = self.p_commercial.code
          end
          st.date = self.date

          st.save


        end



        if self.price_line_block.tot_discount_ht.to_f != 0.0

          st = self.stat_lines.new(:price_line_block_id => self.price_line_block.id, :price_document_number => self.d_number)
          st.date = self.date
          st.title = "Remise pied de page"
          st.price_u_ht = self.price_line_block.tot_discount_ht
          st.price_u_tva = self.price_line_block.tot_discount_tva
          st.price_u_ttc = self.price_line_block.tot_discount_ttc
          st.qte = 1
          st.tot_line_ht = self.price_line_block.tot_discount_ht
          st.tot_line_tva = self.price_line_block.tot_discount_tva
          st.tot_line_ttc = self.price_line_block.tot_discount_ttc

          st.tot_discount_ht = 0
          st.tot_discount_tva = 0
          st.tot_discount_ttc = 0

          st.tot_amount_ht = self.price_line_block.tot_discount_ht
          st.tot_amount_tva = self.price_line_block.tot_discount_tva
          st.tot_amount_ttc = self.price_line_block.tot_discount_ttc

          st.cost_ht = 0
          st.cost_u_ht = 0
          st.cost_u_w_ht = 0
          st.marge_ht = 0
          st.marge_u_ht = 0
          st.marge_u_w_ht = 0
          st.weight_u = 0
          st.weight_tot = 0


          if self.p_customer
            st.p_customer = self.p_customer
            st.p_customer_name = self.p_customer.show_name
            st.p_customer_code = self.p_customer.code
          end

          if self.p_commercial
            st.p_commercial = self.p_commercial
            st.p_commercial_name = self.p_commercial.long_name
            st.p_commercial_code = self.p_commercial.code
          end
          st.date = self.date

          st.save


        end


        if self.price_line_block.tot_fdp_ht.to_f != 0.0

          st = self.stat_lines.new(:price_line_block_id => self.price_line_block.id, :price_document_number => self.d_number)
          st.date = self.date
          st.title = "Frais de port"
          st.price_u_ht = self.price_line_block.tot_fdp_ht
          st.price_u_tva = self.price_line_block.tot_fdp_tva
          st.price_u_ttc = self.price_line_block.tot_fdp_ttc
          st.qte = 1
          st.tot_line_ht = self.price_line_block.tot_fdp_ht
          st.tot_line_tva = self.price_line_block.tot_fdp_tva
          st.tot_line_ttc = self.price_line_block.tot_fdp_ttc

          st.tot_discount_ht = 0
          st.tot_discount_tva = 0
          st.tot_discount_ttc = 0

          st.tot_amount_ht = self.price_line_block.tot_fdp_ht
          st.tot_amount_tva = self.price_line_block.tot_fdp_tva
          st.tot_amount_ttc = self.price_line_block.tot_fdp_ttc

          st.cost_ht = 0
          st.cost_u_ht = 0
          st.cost_u_w_ht = 0
          st.marge_ht = 0
          st.marge_u_ht = 0
          st.marge_u_w_ht = 0
          st.weight_u = 0
          st.weight_tot = 0


          if self.p_customer
            st.p_customer = self.p_customer
            st.p_customer_name = self.p_customer.show_name
            st.p_customer_code = self.p_customer.code
          end

          if self.p_commercial
            st.p_commercial = self.p_commercial
            st.p_commercial_name = self.p_commercial.long_name
            st.p_commercial_code = self.p_commercial.code
          end
          st.date = self.date


          st.save


        end


      end
    end

  end

  def self.update_average_marge
    PriceDocument.order("date ASC").where(:price_document_type_id => 4, :imported => false, :cost_ok => false).where("date < ?", Date.parse("2020/11/10")).find_each do |pd|
      if pd.date < Date.parse("2020/11/01") or (!pd.bon_de_livraison_id or (bl = PriceDocument.where(:id => pd.bon_de_livraison_id).first and bl.date < Date.parse("2020/11/01")))
        pd.price_line_block.update_stocks_from_average

      end
    end
  end

  def self.qi_table_order
    {
      
      :p_customer_code => {:name => "Code client", :reorder => false},
      
      
      :avancement => {:name => "Avancement (%)", :reorder => true},
      :list_designaton => {:name => "Designation liste", :reorder => true},
      :end_date => {:name => "Fin de consultation", :reorder => true},
      :dp_comment => {:name => "Commentaire", :reorder => true},
      :acheteur_text => {:name => "Envoyé à", :reorder => true},
      :customer_ref => {:name => "Ref cotation", :reorder => false},

      
      :p_commercial => {:name => "Commercial", :reorder => false},
      :p_customer => {:name => "Client", :reorder => false},
      :public_fournisseur_name => {:name => "Nom fournisseur saisi", :reorder => false},
      :p_fournisseur => {:name => "Fournisseur", :reorder => false},
      :com_counter => {:name => "N° Offre", :reorder => false},
      :label => {:name => "Type", :reorder => false},
      :d_number => {:name => "Numéro", :reorder => true},
      :date => {:name => "Date", :reorder => true},
      :cc_payment_end_at => {:name => "Date d'échance", :reorder => true},
      :cc_payment_delais  => {:name => "Délais", :reorder => true},
      :p_payment_type => {:name => "Type de paiement"},
      :cc_tot_amount_ht => {:name => "Montant HT", :reorder => true, :sort_name => "cc_tot_amount_ht", :as => :currency},
      :cc_tot_amount_tva => {:name => "TVA", :reorder => true, :sort_name => "cc_tot_amount_tva", :as => :currency},
      :cc_tot_amount_ttc => {:name => "Montant TTC", :reorder => true, :sort_name => "cc_tot_amount_ttc", :as => :currency},
      :cc_solded => {:name => "Soldé ?", :reorder => true, :as => :boolean},
      :reste_to_affect => {:name => "Montant à affecter",:reorder => true},
      :cc_to_paid_ttc => {:name => "Restant dû", :reorder => true, :as => :currency},
      :cc_cost_ht => {:name => "Coût HT", :reorder => true, :as => :currency},
      :cc_marge_ht => {:name => "Marge HT", :reorder => true, :as => :currency},
      :cost_ok => {:name => "Marge calculée", :reorder => true, :as => :boolean},
      :f_token => {:name => "Liens consultation"},
      
      
      
      


      :stock_ok => {:name => "Stock mis à jour ?", :reorder => true},
      :actions => {:name => "Actions", :reorder => false}


    }
    #, :sort_name => "code"
  end

  def self.valid_sort
    r = []
    self.qi_table_order.each do |key, value|
      if value.instance_of? Hash
        if value[:reorder] == false

        elsif value[:reorder] == true
          if value[:sort_name]
            r << value[:sort_name]
          else
            r << key.to_s
          end

        end
      end
    end
    return r


  end


  def personalised_archive
    self.price_line_block.archive_now
  end

  def personalised_unarchive
    self.price_line_block.unarchive_now
  end

  include Rails.application.routes.url_helpers

  QI_DYNAMICS = %w(solded_nbr_days solded_at cost_ht marge_ht weight_tot accounting_zone_id accounting_zone_name tot_amount_ht tot_amount_ttc tot_amount_tva label header footer payment_days payment_delais payment_month_end payment_end_at to_paid_ht to_paid_ttc to_paid_tva solded)


  def reset_for_update
    self.price_line_block.reset_for_update


    QI_DYNAMICS.each do |qid|
      eval("self.ac_#{qid} = nil")
    end
    self.archive_now(:skip_personalised_archive => true)



  end


  eval(QI_DYNAMICS_CORE)

  def to_no_archive
    if self.imported
      %w(solded_nbr_days )
    else
      %w(to_paid_ht to_paid_ttc to_paid_tva solded cost_ht marge_ht solded_at solded_nbr_days)
    end
  end


  attr_accessor :skip_update_caches

  def compta_amount
    self.tot_amount_ttc.to_f * -1
  end

  def compta_date
    self.date
  end


  after_commit do
    if !skip_update_caches
      self.generate_p_compta_element



    end

    self.generate_stat_lines

  end


  before_validation do
    self.verify
    self.p_commercial_id = self.price_line_block.p_commercial_id if self.price_line_block
    self.p_devise_id = self.price_line_block.p_devise_id if self.price_line_block
    self.p_fournisseur_id = self.price_line_block.p_fournisseur_id if self.price_line_block
    self.stock_ok = self.price_line_block.stock_ok if self.price_line_block
    self.cost_ok = self.price_line_block.cost_ok if self.price_line_block

  end

  def ca_cost_ht
    self.price_line_block.cost_ht if self.price_line_block
  end

  def ca_marge_ht
    self.price_line_block.marge_ht if self.price_line_block
  end


  def devise_symbol
    if self.p_devise
      self.p_devise.symbol
    else
      "€"
    end
  end

  after_create do
    generate_number
  end


  def generate_number


    if !self.d_number

      self.d_year = self.date.year


      self.d_prefix = self.price_document_type.prefix.to_s
      self.ac_label = self.price_document_type.label.to_s



      last_number = 0
      last_dt = PriceDocument.where("d_number is not null").where(:d_year => self.d_year,:price_document_type_id => self.price_document_type_id).order("d_index DESC").first

      last_number = last_dt.d_index if last_dt

      self.d_index = last_number+1
      self.d_number = self.d_prefix+self.d_year.to_s+('%05d' % self.d_index)
      self.save


    end
  end


	def verify(size=16)
		if !self.token
			s = ""
			size.times { s << (i = Kernel.rand(62); i += ((i < 10) ? 48 : ((i < 36) ? 55 : 61 ))).chr }
			self.token = s
    end
    
		if !self.f_token
			s = ""
			size.times { s << (i = Kernel.rand(62); i += ((i < 10) ? 48 : ((i < 36) ? 55 : 61 ))).chr }
			self.f_token = s
    end
  end


  def generate_p_compta_element
    if self.id and self.price_document_type.accounting
      if p_compta_element = PComptaElement.where(:element_type => "PriceDocument", :element_id => self.id).first

      else
        p_compta_element = PComptaElement.new(:p_customer => self.p_customer, :element => self)
      end



      p_compta_element.save
    end
  end



  def ca_solded
    if self.to_paid_ttc.to_f >= -0.01 and self.to_paid_ttc.to_f <= 0.01
      true
    else
      false
    end
  end

  def ca_solded_at
    if self.ca_solded

      if p_payment = self.p_payments.order("paid_at DESC").first
        p_payment.paid_at
      else
        nil
      end
    end
  end

  def ca_solded_nbr_days
    if self.solded_at and self.date
      (self.solded_at - self.date).to_i / 1.day.seconds
    else
      nil
    end

  end

  def ca_weight_tot
    self.price_line_block.weight_tot
  end

  def ca_accounting_zone_id
    self.p_customer.accounting_zone.id if self.p_customer and self.p_customer.accounting_zone
  end

  def ca_accounting_zone_name
    self.p_customer.accounting_zone.name if self.p_customer and self.p_customer.accounting_zone
  end

  def ca_tot_amount_ht
    self.price_line_block.tot_amount_ht
  end

  def ca_tot_amount_ttc
    self.price_line_block.tot_amount_ttc
  end

  def ca_tot_amount_tva
    self.price_line_block.tot_amount_tva
  end

  def ca_label
    self.price_document_type.label
  end

  def ca_header
  end

  def ca_footer
  end

  def ca_payment_days
    self.price_line_block.payment_days
  end

  def ca_payment_delais
    self.price_line_block.payment_delais
  end

  def ca_payment_month_end
    self.price_line_block.payment_month_end
  end

  def ca_payment_end_at
    self.price_line_block.ca_payment_end_at
  end

  def ca_particular_bill_id
  end

  def ca_particular_send_id
  end

  def ca_to_paid_ht
  end

  def ca_to_paid_ttc
    if self.label == "Facture"
      self.tot_amount_ttc.to_f - self.p_payment_documents.sum(:amount)
    elsif self.label == "Avoir"
      self.tot_amount_ttc.to_f + self.avoir_p_payment_documents.sum(:amount)
    end

  end

  def ca_to_paid_tva

  end

  def generate_pdf




    doc_number = self.d_number
    url = print_admin_price_document_path(:id => self.token, :html => true)


    @temp_file = "#{Rails.root}/pdf/price_documents/#{doc_number}_temp.pdf"
    @final_file = "#{Rails.root}/pdf/price_documents/#{doc_number}_temp2.pdf"
    @final_file2 = "#{Rails.root}/pdf/price_documents/#{doc_number}.pdf"

    url = (Rails.env.development? ? "http://localhost:4000" : "http://mdmb.basiclabs.fr").to_s+url
    puts url
    pdf = ("pdf")

    node_file = @temp_file


    system("node #{pdf}.js #{Shellwords.escape(url)} #{Shellwords.escape(@temp_file)}")



    require 'posix/spawn'

    ::POSIX::Spawn::Child.new 'pdftk', @temp_file, 'stamp', "#{Rails.root}/pdf_stamp/en-tete.pdf", 'output',  @final_file


    #  ::POSIX::Spawn::Child.new 'pdftk', @final_file,"#{Rails.root}/pdf_stamp/cgv.pdf",  'cat', 'output',  @final_file2  #AJOUT CGV

   # File.rename(@temp_file, @final_file2)


    #File.delete(@temp_file) if File.exist?(@temp_file)
    #File.delete(@final_file) if File.exist?(@final_file)

    return @final_file



  end


  def create_avoir
    past_price_document = self


    price_document = PriceDocument.new(:price_document_type => PriceDocumentType.find_by_label("Avoir"), :date => Date.today, :doc_ref_id => self.id,  :ref_element_type => self.ref_element_type, :ref_element_id=> self.ref_element_id)

    price_document.p_customer = self.p_customer

    price_document.price_line_block = self.price_line_block.dup

    self.price_line_block.price_lines.order("position ASC").each do |pl|
      new_pl = pl.dup
      new_pl.qte = pl.qte * -1
      new_pl.forced_price = true
      if pl.qte != 0.0
        new_pl.ct_u_price_ht =( pl.tot_amount_ht / pl.qte ).to_f.round(3)
      else
        new_pl.ct_u_price_ht = 0
      end

      price_document.price_line_block.price_lines << new_pl
    end

    if past_price_document.price_line_block.tot_fdp_ht.to_f == 0.0
      price_document.price_line_block.ct_tot_fdp_ht = 0.0

    else
      price_document.price_line_block.ct_tot_fdp_ht = (past_price_document.price_line_block.tot_fdp_ht.to_f * -1.0)

    end

    #if price_document.save

    #  price_document.archive_now
    #  self.state = state
    #  self.save

    #end







    return price_document

    #if avoir.element and avoir.element_type == "PCustomerSheet"
    #  avoir.element.state = "remboursée"
    #  avoir.element.save
    #end


    ######





  end


  def block_type
    self.label
  end

  def cancel_now
    self.cancelled = true
    self.save
    if self.price_line_block
      self.price_line_block.save

      self.price_line_block.price_lines.each do |pl|
        pl.save
      end
    end

  end




end
