class PDocument < ApplicationRecord belongs_to :p_document_type has_many :p_sheet_lines, :dependent => :destroy belongs_to :p_customer belongs_to :p_payment_type belongs_to :p_customer_sheet belongs_to :p_sheet_line belongs_to :particular_bill, :class_name => "Particular" belongs_to :particular_send, :class_name => "Particular" belongs_to :p_ship_tour_truck has_many :p_payment_documents, :dependent => :destroy has_many :p_payments, :through => :p_payment_documents has_many :relative_docs, :class_name => "PDocument", :foreign_key => :doc_ref_id has_one :p_compta_element, :as => :element, :dependent => :destroy belongs_to :element, :polymorphic => true validates :d_number, :uniqueness => true accepts_nested_attributes_for :p_sheet_lines, allow_destroy: true attr_accessor :sheet_id, :skip_update_caches include Rails.application.routes.url_helpers after_initialize do if self.element and self.element_type == "PCustomerSheet" and !self.id self.cust_ref = self.element.cust_ref self.comptant = self.element.comptant self.acompte = self.element.acompte self.acompte_percent = self.element.acompte_percent self.payment_delais = self.element.payment_delais self.payment_fin_de_mois= self.element.payment_fin_de_mois self.p_payment_type_id= self.element.p_payment_type_id end end after_save do if !skip_update_caches self.generate_p_compta_element self.p_customer.update_caches if self.p_customer end end def self.update_arrondi PDocument.where("paid = 0 and cache_to_paid >= -1.0 and cache_to_paid <= 1.0").all.each do |p_doc| puts "IDDDDDD" puts p_doc.id p_doc.save end end def arrondi self.p_payment_documents.joins(:p_payment).where(:p_payments => {:p_payment_type_id => 10}).first end def last_paid self.p_payments.order("paid_at DESC").first end before_save do puts self.label self.echeance_date = self.echeance if self.label == "Facture" or self.label == "Avoir" #fdssdfdf = dfsd self.cache_total_ht = self.totals[:ok_total] self.cache_total_ttc = self.totals[:ok_total_ttc] self.cache_total_tva = self.totals[:ok_total_ttc] - self.totals[:ok_total] self.cache_tva = (self.p_sheet_lines.first.tva*100) if self.p_sheet_lines.first #arrondis set_arrondis() self.cache_to_paid = self.total_du self.cache_to_th_paid = self.totals[:ok_total_ttc] - total_paid_th - total_paid else self.cache_total_ht = self.totals[:total] self.cache_total_ttc = self.totals[:total_ttc] self.cache_total_tva = self.totals[:total_ttc] - self.totals[:total] self.cache_tva = (self.p_sheet_lines.first.tva*100) if self.p_sheet_lines.first end end def set_arrondis if self.total_du != 0.0 and self.total_du >= -1.0 and self.total_du <= 1.0 #On fait un arrondi mec ! if self.total_du_without_arrondi != 0.0 and self.total_du_without_arrondi >= -1.0 and self.total_du_without_arrondi <= 1.0 arrondi_amount = self.total_du_without_arrondi if last_paid and arrondi_date = last_paid.paid_at else arrondi_date = Time.now end if self.arrondi arr = self.arrondi arr.amount = arrondi_amount arr.skip_validation = true #arr.save arr.p_payment.amount = arrondi_amount arr.p_payment.paid_at = arrondi_date #arr.p_payment.save else arr = self.p_payments.new(:p_customer_id => self.p_customer_id, :amount => arrondi_amount, :paid => true, :paid_at => arrondi_date, :p_payment_type_id => 10) arr.p_payment_documents << PPaymentDocument.new(:p_document => self, :amount => arrondi_amount, :skip_validation => true) arr.save #puts arr.errors.messages #dqsdqsqs = dsqqds end else self.arrondi.p_payment.destroy if self.arrondi end elsif self.total_du != 0.0 self.arrondi.p_payment.destroy if self.arrondi end true end before_create do archive_particulars end after_create do generate_number archive_sheet_line if self.p_document_type.label != "Avoir" if self.element and self.element_type == "PCustomerSheet" and self.p_document_type.label == "Facture" self.element.p_sheet_lines.each do |p_sheet_line| p_sheet_line.p_payments.order("paid_at ASC, theo_date ASC").each do |p_payment| p_payment.auto_affect(self) self.save end end end if self.element and self.element_type == "PCustomerSheet" and self.p_document_type.label == "Avoir" self.element.state = "remboursée" self.element.save end self.update_paid_status() end before_validation do if !self.id and self.element and self.element_type == "PCustomerSheet" self.p_commercial_id = self.element.p_commercial_id end t = PDocument.where(:doc_ref_id => self.doc_ref_id) if self.id t= t.where("id != ?", self.id) end if self.label == "Avoir" and (!self.id and t.first) # errors.add(:acompte, "Avoir déjà créé") end if self.comptant if self.acompte errors.add(:acompte, "N'est pas compatible avec les paiements comptants") end if self.acompte_percent? errors.add(:acompte_percent, "N'est pas compatible avec les paiements comptants") end if self.payment_delais? errors.add(:payment_delais, "N'est pas compatible avec les paiements comptants") end if self.payment_fin_de_mois errors.add(:payment_fin_de_mois, "N'est pas compatible avec les paiements comptants") end end if self.acompte if !self.acompte_percent? errors.add(:acompte_percent, "Doit être remplis pour demander un acompte") end end if !self.comptant if !self.payment_delais? errors.add(:payment_delais, "Délais de paiement nécessaire si pas de paiement comptant") end end if self.p_document_type self.label = self.p_document_type.label.to_s end if self.sheet_id self.p_sheet_line_id = self.sheet_id end if self.id and self.label == "Facture" self.paid_completed? self.th_paid_completed? end if self.element_type == "PCustomerSheet" self.p_customer = self.element.p_customer end self.verify if !self.id if self.p_document_type.label == "Facture" #or self.p_document_type.label == "Bon de livraison" if PDocument.where(:element_id => self.element_id, :element_type => self.element_type,:p_document_type_id => self.p_document_type_id).count > 0 if self.element_type == "PCustomerSheet" and self.element and self.element.state != "remboursée" errors.add(:element_id, 'Le document existe déjà') end end end end end def generate_p_compta_element if self.id and self.p_document_type_id == 4 or self.p_document_type_id == 7 if p_compta_element = PComptaElement.where(:element_type => "PDocument", :element_id => self.id).first else p_compta_element = PComptaElement.new(:p_customer => self.p_customer, :element => self) end p_compta_element.amount = (self.cache_total_ttc * -1.00) p_compta_element.date = self.created_at p_compta_element.save end end def update_paid_status if self.label == "Facture" self.paid_completed? self.th_paid_completed? self.save end end def archive_particulars if !self.particular_bill and self.element_type == "PCustomerSheet" and self.element.particular_bill self.particular_bill = self.element.particular_bill.dup self.particular_bill.owner = nil self.element.particular_bill.p_contacts.each do |pc| self.particular_bill.p_contacts << pc.dup end end if !self.particular_send and self.element_type == "PCustomerSheet" and self.element.particular_send self.particular_send = self.element.particular_send.dup self.particular_send.owner = nil self.element.particular_send.p_contacts.each do |pc| self.particular_send.p_contacts << pc.dup end end end def archive_sheet_line if self.element_type == "PCustomerSheet" if self.p_document_type.label == "Bon de livraison" if self.sheet_id self.element.p_sheet_lines.where(:cancel => false).where(:id => self.sheet_id).each do |p_sheet_line| n_sheet_line = p_sheet_line.dup n_sheet_line.p_customer_sheet = nil n_sheet_line.p_document = self self.p_sheet_lines << n_sheet_line self.save end else self.element.p_sheet_lines.where(:cancel => false).joins(:p_product).where("'lock' IS NULL OR (p_products.p_product_cat_id != 6 OR (p_products.p_product_cat_id = 6 and externe = 1))").each do |p_sheet_line| n_sheet_line = p_sheet_line.dup n_sheet_line.p_customer_sheet = nil n_sheet_line.p_document = self self.p_sheet_lines << n_sheet_line self.save p_sheet_line.bl = true p_sheet_line.save end end else self.element.p_sheet_lines.where(:cancel => false).joins(:p_product).each do |p_sheet_line| n_sheet_line = p_sheet_line.dup n_sheet_line.p_customer_sheet = nil n_sheet_line.p_document = self self.p_sheet_lines << n_sheet_line self.save end end end end def generate_number if !self.d_number self.d_year = self.element.document_date(self).year self.d_prefix = self.p_document_type.prefix.to_s self.label = self.p_document_type.label.to_s self.header = self.p_document_type.header.to_s self.footer = self.p_document_type.footer.to_s self.image_file_id = self.p_document_type.image_file_id self.data_file_id = self.p_document_type.data_file_id self.name = self.p_document_type.name last_number = 0 last_dt = PDocument.where("d_number is not null").where(:d_year => self.d_year,:p_document_type_id => self.p_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 end def name_for_payment self.created_at.strftime("%d/%m/%Y")+" - "+self.d_number.to_s+" - "+ActionController::Base.helpers.number_to_currency(self.cache_total_ttc)+"("+ActionController::Base.helpers.number_to_currency(self.cache_to_th_paid)+")" end def totals PSheetLine.totals(self.p_sheet_lines) end def total_paid self.p_payment_documents.joins(:p_payment).where(:p_payments => {:paid => true, :canceled => false}).sum(:amount) end def total_paid_without_arrondi self.p_payment_documents.joins(:p_payment).where(:p_payments => {:paid => true, :canceled => false}).where("p_payments.p_payment_type_id != ?",10).sum(:amount) end def total_paid_at end def total_paid_th self.p_payment_documents.joins(:p_payment).where(:p_payments => {:paid => false, :canceled => false}).sum(:amount) end def total_paid_th_at end def total_du_at end def total_du_th_at end def total_du_without_arrondi self.totals[:ok_total_ttc].to_f - self.total_paid_without_arrondi end def total_du self.totals[:ok_total_ttc].to_f - self.total_paid.to_f end def total_du_th self.totals[:ok_total_ttc].to_f - self.total_paid_th.to_f end def th_paid_completed? if self.total_paid_th + self.total_paid == self.totals[:ok_total_ttc].to_f self.theo_paid = true else self.theo_paid = false end end def paid_completed? if self.total_paid.to_f == self.totals[:ok_total_ttc].to_f self.paid = true self.paid_at = self.last_paid.paid_at if self.last_paid else self.paid = false self.paid_at = nil end end def echeance if self.id d = self.created_at else d = Time.now end if self.comptant or self.label == "Avoir" d else d + self.payment_delais.to_i.day end end def generate_pdf @element = self.element doc_number = self.d_number url = admin_p_document_path(:id => self.token, :html => true) if self and self.d_prefix == "BL" @bl = true end @temp_file = "#{Rails.root}/pdf/p_documents/#{doc_number}_temp.pdf" @final_file = "#{Rails.root}/pdf/p_documents/#{doc_number}_temp2.pdf" @final_file2 = "#{Rails.root}/pdf/p_documents/#{doc_number}.pdf" url = (Rails.env.development? ? "http://localhost:4000" : "http://3p.quartz.xyz").to_s+url puts url pdf = (((@bl and self and self.p_sheet_line) ) ? "pdf2" : "pdf") if !@bl or (self and !self.p_sheet_line) node_file = @temp_file else node_file = @final_file2 end system("node #{pdf}.js #{Shellwords.escape(url)} #{Shellwords.escape(@temp_file)}") require 'posix/spawn' if !@bl or (self and !self.p_sheet_line) if self.p_document_type.data_file ::POSIX::Spawn::Child.new 'pdftk', @temp_file, 'background', self.p_document_type.data_file.file.path, 'output', @final_file else ::POSIX::Spawn::Child.new 'pdftk', @temp_file, 'stamp', "#{Rails.root}/pdf_stamp/en-tete.pdf", 'output', @final_file end ::POSIX::Spawn::Child.new 'pdftk', @final_file,"#{Rails.root}/pdf_stamp/cgv.pdf", 'cat', 'output', @final_file2 #AJOUT CGV else File.rename(@temp_file, @final_file2) end File.delete(@temp_file) if File.exist?(@temp_file) File.delete(@final_file) if File.exist?(@final_file) return @final_file2 end def create_avoir p_document = self avoir = PDocument.new(:created_at => self.created_at, :label => "Avoir", :doc_ref_id => self.id, :doc_ref_number => self.d_number, :p_document_type => PDocumentType.find_by_label("Avoir"), :element_type => self.element_type, :element_id => self.element_id, :p_customer_id => self.p_customer_id, :particular_bill_id => self.particular_bill_id, :particular_send_id => self.particular_send_id) self.p_sheet_lines.each do |p_sheet_line| new_psl = p_sheet_line.dup new_psl.qte = (new_psl.qte*-1) new_psl.ok_qte = (new_psl.ok_qte*-1) new_psl.imported = false new_psl.arrondi = false puts new_psl.ok_qte #dgfgdf = fdfg avoir.p_sheet_lines << new_psl end return avoir #if avoir.element and avoir.element_type == "PCustomerSheet" # avoir.element.state = "remboursée" # avoir.element.save #end ###### end end