diff --git a/app/assets/javascripts/admin.coffee b/app/assets/javascripts/admin.coffee index 3a1ef36..eadb77a 100644 --- a/app/assets/javascripts/admin.coffee +++ b/app/assets/javascripts/admin.coffee @@ -43,6 +43,16 @@ window.disable_portlet_select = false window.portlet_change = false +@resize = () -> + header_size = $("#admin_nav").outerHeight() + + if $(".qi_header").length > 0 + + header_size = header_size + $(".qi_header").first().outerHeight() + + $("body").css("padding-top", header_size+"px") + + @edit_watcher = (element_type, element_id, key) -> $.ajax @@ -646,4 +656,11 @@ $(document).on "click", "#menu_item_informations h4", -> return false +$ -> + $(window).on "resize", -> + resize() + + + + resize() diff --git a/app/assets/stylesheets/admin.css.scss b/app/assets/stylesheets/admin.css.scss index c26a294..384cdaa 100644 --- a/app/assets/stylesheets/admin.css.scss +++ b/app/assets/stylesheets/admin.css.scss @@ -1072,4 +1072,160 @@ input[type=number]::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; } + +//CSS 3P + + +.table-striped > tbody > tr:nth-child(odd) > td, .table-striped tr:nth-child(odd) td, .table-striped tr:nth-child(odd) th{ + +//background:rgba(235,244,250,1) ; + +} +.table-striped { + + tr:nth-child(odd){ + th{ + background:transparent !important; + } + } +} + +.table-striped{ + + tr:nth-child(odd) { + td, th{ + background:#f9f9fe ; + }} + + tr{ + th{ + background:transparent !important; + + } + } + +} + + +.table-hover > tbody > tr:hover{ + td{ + + background:#f1f1fe ;} + +} + + + + +.round{ + width:10px; + height:10px; + display:inline-block; + border-radius:50%; + + &.green{ + background:green;} + &.orange{ + background:orange} + &.red{ + background:red} + +} + + +.en-tete-table{ + table{ + border-collapse:collapse; + } + td,th{ + border:1px solid black; + padding:3px 5px; + } +} + +#admin_nav{ +border-radius:0px; +position:fixed; +right:0; +left:100px; +top:0; +z-index:10; +.active{ + color:white; + border-bottom:1px solid white; +} + +} +.qi_header{ + position:fixed; + z-index:3; + box-shadow:0 0 5px rgba(0,0,0,0.2); + top:50px; + right:0; + left:100px; + min-height:48px; +} + +.p_customer_particulars{ + padding-top:30px; + vertical-align:top; + white-space: nowrap; + overflow:auto; + + .particular_apercu{ + vertical-align:top; + display:inline-block; + margin: 0 10px; + width:300px; + white-space: normal; + margin-bottom:20px; + + + } + + .qi_pannel{ + padding:10px; + } + + .prim{ + .qi_pannel{ + border-top:4px solid green; + padding-top:6px; + } + } + +} + + +.bottom_fixed{ + + .qi_pagination{ + border:0; + padding:0; + margin:0; + text-align:left; + padding-left:20px; + + } + position:fixed; + bottom:0; + left:100px; + right:0; + box-shadow:0 0 5px rgba(0,0,0,0.2); + background:white; + padding:20px; +} + + +td.actions{ + + text-align:right; +} + + +td.numeraire{ + white-space: nowrap; + text-align:right; +} + diff --git a/app/controllers/admin/p_customers_controller.rb b/app/controllers/admin/p_customers_controller.rb index d427dd1..67fe245 100644 --- a/app/controllers/admin/p_customers_controller.rb +++ b/app/controllers/admin/p_customers_controller.rb @@ -115,8 +115,107 @@ class Admin::PCustomersController < ApplicationController end def etat - @p_customer = PCustomer.find(params[:id]) + @p_customer = PCustomer.find(params[:id]) if params[:id] + + + + + + + date_regex = /^(0[1-9]|[12][0-9]|3[01])[\/](0[1-9]|1[012])[\/](19|20)\d\d$/i + + if params[:start] and params[:start] =~ date_regex + @start = Date.parse(params[:start]).beginning_of_day + params[:start]= @start.strftime('%d/%m/%Y') + else + @start = nil + end + + + + if params[:stop] and params[:stop] =~ date_regex + @stop = Date.parse(params[:stop]).end_of_day + params[:stop]= @stop.strftime('%d/%m/%Y') + else + @stop = nil + end + + if !@p_customer and !@start + @start = Date.today.beginning_of_year + params[:start]= @start.strftime('%d/%m/%Y') + end + + + + if @p_customer + @p_compta_elements = @p_customer.p_compta_elements.order("date DESC") + else + @p_compta_elements = PComptaElement.order("date DESC") + end + + @p_compta_elements = @p_compta_elements.where("date >= ?", @start) if @start + + @p_compta_elements = @p_compta_elements.where("date < ?", @stop.end_of_day) if @stop + params[:ok] = "0" if params[:ok].to_s == "" and !@p_customer + if params[:ok].to_s != "" + if params[:ok] == "1" + @p_compta_elements = @p_compta_elements.where(:solde => true) + else + @p_compta_elements = @p_compta_elements.where(:solde => false) + end + end + + + + + + + + params[:inline] = true + if params[:pdf] == "true" + + require 'posix/spawn' + + doc_number = ""+params[:id].to_s + #url = adr_admin_p_ship_tour_path(:id => params[:id],:html => true) + url = url_for( request.query_parameters.merge({html: true, pdf: false, :only_path => true})) + puts "AAA" + puts url + @final_file = "#{Rails.root}/pdf/p_documents/etat-#{doc_number}.pdf" + @temp_file = "#{Rails.root}/pdf/p_documents/etat-#{doc_number}-temp.pdf" + + + + + url = (Rails.env.development? ? "http://localhost:4000" : "http://3p.quartz.xyz").to_s+url + puts url + pdf = "pdfportrait" + command = "node #{pdf}.js #{Shellwords.escape(url)} #{Shellwords.escape(@temp_file)}" + puts command + system(command) + + + ::POSIX::Spawn::Child.new 'pdftk', @temp_file, 'stamp', "#{Rails.root}/pdf_stamp/en-tete.pdf", 'output', @final_file + + @data_to_send = File.open( @final_file).read + + + send_data @data_to_send, :filename =>"#{doc_number}.pdf" , :type => 'application/pdf',:disposition => (params[:inline] ? 'inline' : "attachment") + else + render :layout => false if params[:html] + end + + + + + + + + end + + + end diff --git a/app/controllers/admin/p_documents_controller.rb b/app/controllers/admin/p_documents_controller.rb index aba42ff..1735266 100755 --- a/app/controllers/admin/p_documents_controller.rb +++ b/app/controllers/admin/p_documents_controller.rb @@ -23,7 +23,11 @@ class Admin::PDocumentsController < ApplicationController @p_documents = @p_documents.all render :layout => "admin" end - + def detail + @p_document = PDocument.find(params[:id]) + + render :layout => "admin" + end def show @p_document = PDocument.find_by_token(params[:id]) @element = @p_document.element diff --git a/app/controllers/admin/p_payments_controller.rb b/app/controllers/admin/p_payments_controller.rb index a2203e5..584d287 100644 --- a/app/controllers/admin/p_payments_controller.rb +++ b/app/controllers/admin/p_payments_controller.rb @@ -11,7 +11,7 @@ class Admin::PPaymentsController < ApplicationController end def index - @p_payments = PPayment.order("created_at ASC").all + @p_payments = PPayment.order("created_at DESC").all end diff --git a/app/models/p_compta_element.rb b/app/models/p_compta_element.rb new file mode 100644 index 0000000..6685c1e --- /dev/null +++ b/app/models/p_compta_element.rb @@ -0,0 +1,38 @@ +class PComptaElement < ActiveRecord::Base + belongs_to :p_customer + belongs_to :element, :polymorphic => true + before_save do + + + + if self.solde_ok? + self.solde = true + else + self.solde = false + + end + + true + end + + def solde_ok? + if self.element + if self.element_type == "PDocument" + if self.element.paid + return true + else + return false + end + + elsif self.element_type == "PPayment" + if self.element.reste_to_affect == 0.0 + return true + else + return false + end + end + else + false + end + end +end diff --git a/app/models/p_customer.rb b/app/models/p_customer.rb index a552045..030d011 100644 --- a/app/models/p_customer.rb +++ b/app/models/p_customer.rb @@ -23,15 +23,42 @@ class PCustomer < ActiveRecord::Base has_many :p_documents - + has_many :p_payments belongs_to :p_price_cat + has_many :p_compta_elements + attr_accessor :valid_public, :generate_mdp, :valid_siren before_validation do self.generate_token if !self.token? and self.email? end + + + def update_caches + + self.cache_encours = self.encours_ttc + # + self.cache_payments = self.paiements_total + + self.cache_ca = self.ca_ht + + self.cache_ca_ttc = self.ca_ttc + + self.save + + + end + + def ca_ht + 0 + end + + def ca_ttc + 0 + end + def valid_siren? true if self.valid_siren end @@ -181,5 +208,26 @@ class PCustomer < ActiveRecord::Base PCustomerMailer.password_reset(self).deliver end + + def encours_ttc + self.solde_avoir_and_bills - self.paiements_total + end + + def encours_at(date) + self.solde_avoir_and_bills(date) - self.paiements_total(date) + end + + def solde_avoir_and_bills(date = Date.today) + self.p_documents.where(:p_document_type_id => PDocument::COMPTA_DOC_TYPES).where("created_at < ?", date.to_time.end_of_day).sum(:cache_total_ttc) + + end + + def paiements_total(date = Date.today) + self.p_payments.where(:paid => true).where("paid_at < ?", date.to_time.end_of_day).sum(:amount) + + end + + + end diff --git a/app/models/p_document.rb b/app/models/p_document.rb index 9c803e1..5cf2017 100644 --- a/app/models/p_document.rb +++ b/app/models/p_document.rb @@ -13,14 +13,60 @@ class PDocument < ActiveRecord::Base has_many :relative_docs, :class_name => "PDocument", :foreign_key => :doc_ref_id + COMPTA_DOC_TYPES = [4,7] has_many :p_payment_documents, :dependent => :destroy + has_many :p_payments, :through => :p_payment_documents + belongs_to :element, :polymorphic => true - attr_accessor :sheet_id + attr_accessor :sheet_id, :skip_update_caches + + before_save do + puts self.label + self.echeance_date = self.echeance + + + self.cache_total_ht = self.totals[:total].to_f + self.cache_total_ttc = self.totals[:total_ttc].to_f + self.cache_total_tva = self.totals[:total_ttc].to_f - self.totals[:total].to_f + self.cache_tva = (self.p_sheet_lines.first.tva*100) if self.p_sheet_lines.first + + + + self.cache_to_paid = self.total_du + + + + + + 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 generate_p_compta_element + if self.id and PDocument::COMPTA_DOC_TYPES.include?(self.p_document_type_id) + 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.to_f * -1.00) + p_compta_element.date = self.created_at + + p_compta_element.save + end + end after_initialize do @@ -286,11 +332,12 @@ class PDocument < ActiveRecord::Base end def paid_completed? - if self.total_paid.to_f == self.totals[:total_ttc].to_f + if self.total_paid.to_f.round(2) == self.totals[:total_ttc].to_f.round(2) self.paid = true else self.paid = false end + end diff --git a/app/models/p_payment.rb b/app/models/p_payment.rb index 53d317d..26456a0 100644 --- a/app/models/p_payment.rb +++ b/app/models/p_payment.rb @@ -9,6 +9,10 @@ class PPayment < ActiveRecord::Base has_many :p_payment_documents accepts_nested_attributes_for :p_payment_documents, allow_destroy: true + has_one :p_compta_element, :as => :element, :dependent => :destroy + + + before_validation do @@ -32,7 +36,32 @@ class PPayment < ActiveRecord::Base self.p_payment_documents.each do |p_payment_document| p_payment_document.save end + self.generate_p_compta_element + self.p_customer.update_caches if self.p_customer + true + end + + + + + def generate_p_compta_element + if self.p_compta_element + p_compta_element = self.p_compta_element + else + p_compta_element = PComptaElement.new(:p_customer => self.p_customer, :element => self) + end + + p_compta_element.amount = (self.amount) + if self.paid_at? + p_compta_element.date = self.paid_at + elsif self.theo_paid_at? + p_compta_element.date = self.theo_paid_at + else + p_compta_element.date = self.created_at + end + puts p_compta_element.save + end def total_affected @@ -51,4 +80,8 @@ class PPayment < ActiveRecord::Base true if self.p_payment_type and !self.p_payment_type.comptant end + def reste_to_affect + (self.amount.to_f - self.total_affected.to_f).round(2) + end + end diff --git a/app/models/p_sheet_line.rb b/app/models/p_sheet_line.rb index 39d1491..4714c51 100644 --- a/app/models/p_sheet_line.rb +++ b/app/models/p_sheet_line.rb @@ -369,20 +369,20 @@ class PSheetLine < ActiveRecord::Base tva = 0.0 sheet_lines.each do |sheet_line| tva = sheet_line.tva - total += sheet_line.price_tot - total_ttc += sheet_line.price_tot_ttc + total += sheet_line.price_tot.to_f.round(2) + total_ttc += sheet_line.price_tot_ttc.to_f.round(2) end r[:total_articles] = {:label =>"Total articles HT",:value => total} fdp = 0 - fdp = PSheetLine.frais_de_port(sheet_lines) + fdp = PSheetLine.frais_de_port(sheet_lines).to_f.round(2) r[:fdp] = {:label =>"Frais de port HT",:value => fdp} - total = total +fdp.to_f - total_ttc = total_ttc + (fdp.to_f*(1+tva)) + total = total.to_f.round(2) +fdp.to_f.round(2) + total_ttc = total_ttc.to_f.round(2) + (fdp.to_f*(1+tva)).to_f.round(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} diff --git a/app/views/admin/p_compta_elements/_p_compta_element.html.haml b/app/views/admin/p_compta_elements/_p_compta_element.html.haml new file mode 100644 index 0000000..2f58ce1 --- /dev/null +++ b/app/views/admin/p_compta_elements/_p_compta_element.html.haml @@ -0,0 +1,65 @@ +-#p_compta_element.save + +%tr#p_compta_element{:id => p_compta_element.id} + -if !@p_customer + %td + -if !params[:html] + =link_to p_compta_element.p_customer.show_name, [:admin, p_compta_element.p_customer ] + -else + =p_compta_element.p_customer.show_name + + %td + =l p_compta_element.date, :format => :date + + -if p_compta_element.element + %td + =l p_compta_element.element.echeance_date, :format => :date if p_compta_element.element_type == "PDocument" and p_compta_element.element.echeance_date + + + %td + -if p_compta_element.element_type == "PDocument" + =p_compta_element.element.label + -else + Paiement + %td + -if p_compta_element.element_type == "PDocument" + + -if !params[:html] + =link_to p_compta_element.element.d_number, admin_p_document_path(p_compta_element.element.token) + -else + =p_compta_element.element.d_number + + + -elsif p_compta_element.element and p_compta_element.element_type == "PPayment" + =p_compta_element.element.p_payment_type.name + =#p_compta_element.save + %td.right_text + -if p_compta_element.amount < 0.0 + =number_to_currency (p_compta_element.amount * -1) + + %td.right_text + -if p_compta_element.amount >= 0.0 + =number_to_currency p_compta_element.amount + + %td{:style => "width:20px"} + -if !params[:html] + =ic(:check) if p_compta_element.solde + -else + ="Oui" if p_compta_element.solde + + -if !@p_customer + %td + -if p_compta_element.element_type == "PDocument" + =number_to_currency p_compta_element.element.cache_to_paid + -else + =number_to_currency p_compta_element.element.reste_to_affect + + + -if !params[:html] + %td.actions + -if p_compta_element.element_type == "PDocument" + =link_to i(:eye), detail_admin_p_document_path(p_compta_element.element), :remote => false if true + =link_to i(:pencil), edit_admin_p_document_path(p_compta_element.element), :remote => true + + -elsif p_compta_element.element + =link_to i(:pencil), edit_admin_p_payment_path(p_compta_element.element), :remote => true \ No newline at end of file diff --git a/app/views/admin/p_customer_sheets/_p_customer_sheet.html.haml b/app/views/admin/p_customer_sheets/_p_customer_sheet.html.haml index 7744d47..aa78ed9 100644 --- a/app/views/admin/p_customer_sheets/_p_customer_sheet.html.haml +++ b/app/views/admin/p_customer_sheets/_p_customer_sheet.html.haml @@ -10,6 +10,9 @@ %td -totals = PSheetLine.totals(p_customer_sheet.p_sheet_lines) =number_to_currency totals[:total] + + %td + =number_to_currency totals[:total_ttc] %td=raw p_customer_sheet.state_html diff --git a/app/views/admin/p_customers/_etat.html.haml b/app/views/admin/p_customers/_etat.html.haml new file mode 100644 index 0000000..5caa698 --- /dev/null +++ b/app/views/admin/p_customers/_etat.html.haml @@ -0,0 +1,29 @@ +%table.table.table-hover.table-striped#p_customer_etat{:id => p_customer.id} + %thead + %tr + + %th Date + %th Echeance + %th Type + %th Réf + %th Débit + %th Crédit + %th Soldé ? + %th.action + + %tbody.lines + =render p_customer.p_compta_elements.order("date DESC") + + %tr + %th{:colspan => 4} + Solde : + =number_to_currency p_customer.p_compta_elements.sum(:amount) + %th + -a = p_customer.p_compta_elements.where("amount < 0.0").sum(:amount) + =number_to_currency (a*-1) + %th + -b = p_customer.p_compta_elements.where("amount > 0.0").sum(:amount) + =number_to_currency b + %th + %th + \ No newline at end of file diff --git a/app/views/admin/p_customers/_p_customer.html.haml b/app/views/admin/p_customers/_p_customer.html.haml index 35beda2..866140e 100644 --- a/app/views/admin/p_customers/_p_customer.html.haml +++ b/app/views/admin/p_customers/_p_customer.html.haml @@ -2,6 +2,15 @@ %td= p_customer.email %td= p_customer.code %td= p_customer.show_name + + %td= p_customer.particular.cp if p_customer.particular + %td= p_customer.particular.city if p_customer.particular + %td + -if p_customer.cache_encours < 0 + %span{:style => "color:green"}=number_to_currency p_customer.cache_encours + -elsif p_customer.cache_encours > 0 + %span=number_to_currency p_customer.cache_encours + -if false %td{:style => "text-align:right;"}=number_to_currency p_customer.p_customer_sheets.sum(:a_ok_total) diff --git a/app/views/admin/p_customers/_search_etat_form.html.haml b/app/views/admin/p_customers/_search_etat_form.html.haml new file mode 100644 index 0000000..56e733a --- /dev/null +++ b/app/views/admin/p_customers/_search_etat_form.html.haml @@ -0,0 +1,34 @@ +=form_tag (@p_customer ? etat_admin_p_customer_path(@p_customer) : etat_admin_p_customers_path), :method => "get", :remote => false, :autocomplete => "off" do + + %table + %tr + %td.search_label + Début + %td + .input-group + =text_field_tag :start, params[:start],:class => "form-control datepicker", :placeholder => "Début" + %span.input-group-addon.btn{:onclick => "$(this).prev('input').val('');"} + =ic(:times) + %td.search_label + Fin + %td + .input-group + =text_field_tag :stop, params[:stop],:class => "form-control datepicker", :placeholder => "Fin" + %span.input-group-addon.btn{:onclick => "$(this).prev('input').val('');"} + =ic(:times) + + %td.search_label + Soldé ? : + + + + + %td + =select_tag :ok, options_for_select([["Non","0"], ["Oui","1"]], params[:ok]), :include_blank => true + + %br + %center + -if @p_customer + =submit_tag "Générer un état", :class => "btn btn-default", :style => "margin-bottom: 10px;" + -else + =submit_tag "Générer un état pour tous les clients avec un encours (#{PCustomer.where('cache_encours != 0.0').count})", :class => "btn btn-default", :style => "margin-bottom: 10px;" \ No newline at end of file diff --git a/app/views/admin/p_customers/etat.html.haml b/app/views/admin/p_customers/etat.html.haml new file mode 100644 index 0000000..4f7fffc --- /dev/null +++ b/app/views/admin/p_customers/etat.html.haml @@ -0,0 +1,242 @@ +-#PDocument.update_arrondi + +-if !params[:html] and @p_customer + .qi_header + .right + = link_to "Retour à la fiche client",[:admin, @p_customer], :class => "btn btn-primary" + %h1 + Clients + %span + Détail d'un client + %span + =link_to [:admin, @p_customer] do + =@p_customer.code + =@p_customer.show_name + + .qi_row + .qi_pannel.qi_plain.padding + =render :partial => "search_etat_form" + +.qi_row + .qi_pannel.qi_plain.padding + -if !params[:html] + .right + =link_to "Télécharger en PDF", request.query_parameters.merge({pdf: true}), :class => "btn btn-primary" + + -if params[:html] and @p_customer + + + + %div{:style => "height:0cm;"} + + =#;top:5cm; + %div{:style => "position:relative;width:6.4cm;margin-right:1.5cm;float:right;"} + %div{:style => "padding:4px 8px;min-height:80px;"} + %h3{:style => "position:absolute;top:-40px;"} Adresse de facturation + + %strong=@p_customer.particular.organisation + %br + =@p_customer.particular.name + =@p_customer.particular.firstname + + + -if @p_customer.particular.address_2? + %br + =@p_customer.particular.address_2 + + -if @p_customer.particular.address_3? + %br + =@p_customer.particular.address_3 + -if @p_customer.particular.cp? or @p_customer.particular.city? + %br + =@p_customer.particular.cp + + =@p_customer.particular.city + %br + =@p_customer.particular.country + + %p + A Moirans, le + =l Date.today + + %div{:style => "height:2.6cm;"} + + + %p Bonjour + + + %p Veuillez trouver votre relevé de compte ci-dessous et de nous faire parvenir un règlement si des échéances sont dépassées. + + %p Merci de vérifier si vous avez en votre possession toutes les factures référencées, si cela n’était pas le cas merci de nous le signaler. + + + %p Cordialement + + %hr + + + + %h1 Etat de compte + + -if !@p_customer + %p + =@p_compta_elements.count + résultats + + + + -if params[:ok].to_s != "" + Opérations + -if params[:ok] == "1" + soldées + -else + non soldées + + -if @start and @stop + du + =l (@start), :format => :date + au + =l (@stop), :format => :date + + -elsif @start + à partir du + =l (@start), :format => :date + -elsif @stop + jusqu'au + =l (@stop), :format => :date + + + %table.table.table-hover.table-striped#p_customer_etat{:id => (@p_customer.id if @p_customer)} + %thead + %tr + -if !@p_customer + %th Client + %th Date + %th Echéance + %th Type + %th Réf + %th Débit + %th Crédit + %th{:style => "width:20px"} Soldé ? + -if !@p_customer + %th Solde + -if !params[:html] + %th.action + + -if @stop and params[:ok].to_s == "" and @p_customer + %tbody + %tr + %th{:colspan => (@p_customer ? 4 : 5)} + Solde au + =l (@stop), :format => :date + + + - a = (@p_customer.encours_at(@stop) * -1) + - a = 0.0 if a == -0.0 + %th + -if a < 0 + =number_to_currency a + %th + -if a >= 0 + =number_to_currency a + %th + -if !@p_customer + %th + -if !params[:html] + %th + + + + + %tbody=render @p_compta_elements + + %tbody + %tr + %th{:colspan => (@p_customer ? 4 : 5)} + Total + %th.right_text + -a = @p_compta_elements.where("amount < 0.0").sum(:amount) + =number_to_currency (a * -1) + %th.right_text + -b = @p_compta_elements.where("amount > 0.0").sum(:amount) + =number_to_currency b + %th + -if !@p_customer + %th + -if !params[:html] + %th + + + -if @start and params[:ok].to_s == "" and @p_customer + %tbody + %tr + %th{:colspan => (@p_customer ? 4 : 5)} + Solde au + =l (@start - 1.second), :format => :date + + - a = (@p_customer.encours_at(@start - 1.second) * -1) + - a = 0.0 if a == -0.0 + %th.right_text + -if a < 0 + =number_to_currency a + %th.right_text + -if a >= 0 + =number_to_currency a + %th + -if !@p_customer + %th + -if !params[:html] + %th + + -if !@stop and @p_customer + %p + Encours du compte : + %strong + =number_to_currency @p_customer.encours_ttc + + + +-if params[:html] + :scss + body{ + font-family: arial, sans-serif; + font-size:10pt; + padding:0; + margin:0; + } + .page{ + page-break-after: always; + position:relative; + width:28.1cm; + box-sizing:border-box; + + + } + + .table{ + width:100%; + font-size:10pt; + border-collapse:collapse; + td, th{ + border:1px solid black; + padding:2px 5px; + page-break-inside: avoid !important; + + } + td{ + vertical-align:top; + } + th{ + text-align:left; + vertical-align:top; + } + .right_text{ + text-align:right; + } + } + + + + + + diff --git a/app/views/admin/p_customers/index.html.haml b/app/views/admin/p_customers/index.html.haml index 1ce2b12..ba23427 100644 --- a/app/views/admin/p_customers/index.html.haml +++ b/app/views/admin/p_customers/index.html.haml @@ -17,7 +17,9 @@ %th Email %th Code %th Nom - %th CA (HT) + %th CP + %th Ville + %th Encours %th @@ -43,6 +45,9 @@ %th Email %th Code %th Nom + %th CP + %th Ville + %th Encours %th diff --git a/app/views/admin/p_customers/show.html.haml b/app/views/admin/p_customers/show.html.haml index 1d8fb02..11ca6c9 100644 --- a/app/views/admin/p_customers/show.html.haml +++ b/app/views/admin/p_customers/show.html.haml @@ -15,30 +15,178 @@ Code parrain : %strong=@p_customer.mlm_token - %hr + + +.qi_row#tabs + .qi_pannel + %ul.nav.nav-tabs + -params[:tab] = params[:tab] || "offres" + %li{:class => ("active" if params[:tab] == "offres")}=link_to "Offres", "?tab=offres#tabs" + %li{:class => ("active" if params[:tab] == "etat")}=link_to "Etat de compte", "?tab=etat#tabs" + %li{:class => ("active" if params[:tab] == "bills")}=link_to "Factures & Avoirs", "?tab=bills#tabs" + %li{:class => ("active" if params[:tab] == "payments")}=link_to "Paiements", "?tab=payments#tabs" - %h3 Offres - .right - =link_to "Nouvelle offre pour le client", new_admin_p_customer_sheet_path(:p_customer_id => @p_customer.id) - .clear + .tab-content{:style => "min-height:1000px;margin-bottom:300px;"} + -if params[:tab] == "offres" + #offres + .qi_row + .qi_pannel.qi_plain.padding + .right + =link_to "Nouvelle offre pour le client", new_admin_p_customer_sheet_path(:p_customer_id => @p_customer.id), :class => "btn btn-primary bgbd-ventes" + %h3 Offres + .clear - %table.table - %tr - %th ID - %th Date + %hr + -if false + %p + CA HT : + =number_to_currency @p_customer.sheets_total_ht + %p + CA TTC : + =number_to_currency @p_customer.solde_avoir_and_bills + + + %hr + + %table.table.table-hover.table-striped + %tr + %th ID + %th Date - %th Non livrés - %th Livrés - %th Total HT - %th Statut + %th Non livrés + %th Livrés + %th Total HT + %th Total TTC + %th Statut - %th + %th - %tbody#p_customer_sheets_rows - =render @p_customer.p_customer_sheets.order("created_at DESC") + %tbody#p_customer_sheets_rows + - @p_customer_sheets = @p_customer.p_customer_sheets.order("created_at DESC") + -per_page = (params[:per_page] and params[:per_page] != "") ? params[:per_page] : 30 + -page = (params[:page] and params[:page] != "") ? params[:page] : 1 + -@p_customer_sheets = @p_customer_sheets.page(page).per(per_page) + + =render @p_customer_sheets + + .qi_pagination + = paginate @p_customer_sheets + + -if params[:tab] == "etat" + #etat + .qi_row + .qi_pannel.qi_plain.padding + .right + = link_to 'Ajouter un paiement', new_admin_p_payment_path(:p_customer_id => @p_customer.id), :class => "btn btn-primary bgbd-payments", :remote => true + + %h3 + Etat de compte + + + =render :partial => "search_etat_form" + - %hr - =#debug @p_customer \ No newline at end of file + -if false + -@p_customer.p_compta_elements.destroy_all + -@p_customer.p_documents.each do |pd| + -pd.save + + -@p_customer.p_payments.each do |pd| + -pd.save + + + =render :partial => "admin/p_customers/etat", :locals => {:p_customer => @p_customer} + + -if params[:tab] == "bills" + #bills + .qi_row + .qi_pannel.qi_plain.padding + + %h3 + Factures & acomptes + =#%p + =#link_to "Documents du client", admin_p_customer_p_documents_path(@p_customer) + .clear + + + %hr + -if params[:doc_label] + %p + Factures + =params[:doc_label] + %table.table.table-hover.table-striped + %tr + + %th Date + %th Offre + %th Client + %th Type + %th Numéro + %th Total HT + %th Total TTC + %th + Payée + %th Solde + %th Echéance + + %th Jours de retard + %th + + + %tbody#p_customer_sheets_rows + -@p_documents = @p_customer.p_documents.order("created_at DESC") + -@p_documents = @p_documents.where(:p_document_type_id => PDocument::COMPTA_DOC_TYPES) + -if params[:p_document_ids] + -@p_documents = @p_documents.where(:id => params[:p_document_ids]) + =render @p_documents + + + + + + -if params[:tab] == "payments" + #payments + + + .qi_row + .qi_pannel.qi_plain.padding + .right + = link_to 'Ajouter un paiement', new_admin_p_payment_path(:p_customer_id => @p_customer.id), :class => "btn btn-primary bgbd-payments", :remote => true + %h3 + Paiements + ="(#{@p_customer.p_payments.count})" + .clear + + + + %hr + + %p + Total paiements : + =number_to_currency @p_customer.paiements_total + + %hr + + %table.table.table-hover.table-striped + %tr + %th + %th Type de paiement + %th Date de paiement + %th Date théorique + + %th Client + %th Montant + %th Montant à affecter + %th + %th + %th + + + %tbody#p_payments_rows + =render @p_customer.p_payments.order("paid_at DESC") + + + diff --git a/app/views/admin/p_documents/_p_document.html.haml b/app/views/admin/p_documents/_p_document.html.haml index ea1a455..1f5af39 100644 --- a/app/views/admin/p_documents/_p_document.html.haml +++ b/app/views/admin/p_documents/_p_document.html.haml @@ -1,63 +1,153 @@ -%tr +-if false + %tr + %td + =l p_document.created_at, :format => :date + + -if @p_documents + %td + =link_to "##{p_document.element.id}", admin_p_customer_sheet_path(p_document.element) + %td + =p_document.element.p_customer.show_name if p_document.element and p_document.element.p_customer + + + + %td + =p_document.label + %td + =link_to p_document.d_number, admin_p_document_path(p_document.token) + + -totals = PSheetLine.totals(p_document.p_sheet_lines) + %td + = number_to_currency totals[:total] + HT + + %td + = number_to_currency totals[:total_ttc] + TTC + + -if params[:p_document_type_id].to_i == 4 + %th + ="oui" if p_document.theo_paid + %th + ="oui" if p_document.paid + + + -if false + %table + %tr + %td + Paid + %td + =p_document.paid + %tr + %td + TH Paid + %td + =p_document.theo_paid + -p_document.p_payment_documents.each do |pp| + %tr + %td + =pp.amount + %td + =pp.paid + =pp.p_payment.paid + + + + %td.actions + -if p_document.label == "Facture" and !@relances + -#if p_document.relative_docs.where(:label => "Avoir").count == 0 + =link_to "Créer un avoir", create_avoir_admin_p_document_path(p_document) #, :data => {:confirm => "Voulez-vous vraiment créer un avoir ?"} +    + =link_to i(:eye), detail_admin_p_document_path(p_document) + + + + -skip_bill_details = skip_bill_details || false + + + +%tr#p_document{:id => p_document.id} + + + + -if @case_multiple + %td + =check_box_tag "ids[]", p_document.token + + + %td =l p_document.created_at, :format => :date - - -if @p_documents + + + + -if !@p_customer_sheet %td =link_to "##{p_document.element.id}", admin_p_customer_sheet_path(p_document.element) + + -if p_document.p_customer %td - =p_document.element.p_customer.show_name if p_document.element and p_document.element.p_customer - - + =link_to p_document.p_customer.show_name, [:admin, p_document.p_customer] + + %td =p_document.label %td =link_to p_document.d_number, admin_p_document_path(p_document.token) - -totals = PSheetLine.totals(p_document.p_sheet_lines) - %td - = number_to_currency totals[:total] - HT + %td.numeraire + = number_to_currency p_document.cache_total_ht + + + %td.numeraire + = number_to_currency p_document.cache_total_ttc - %td - = number_to_currency totals[:total_ttc] - TTC + + + + -if (!skip_bill_details) + + %td + =ic(:check) if p_document.paid - -if params[:p_document_type_id].to_i == 4 - %th - ="oui" if p_document.theo_paid - %th - ="oui" if p_document.paid + %td.numeraire + -if p_document.cache_to_paid? + =number_to_currency p_document.cache_to_paid + + + %td + =l p_document.echeance_date, :format => :date if p_document.echeance_date + %td + -if p_document.label == "Facture" or p_document.label == "Facture Acompte" + -if p_document.echeance_date and !p_document.paid + -j = (Date.today - p_document.echeance_date).to_i + + -if j > 0 + %span{:style => "color:red;"} + =j + -else + %span{:style => "color:green;"} + =j + + + %td.actions + -if p_document.label == "Facture" and !@relances + -if p_document.relative_docs.where(:label => "Avoir").count == 0 or true + =link_to "Créer un avoir", create_avoir_admin_p_document_path(p_document), :data => {:confirm => "Voulez-vous vraiment créer un avoir ?"} +    + =link_to i(:eye), detail_admin_p_document_path(p_document), :remote => false + + -if false + -if p_document.compta_locked + =ic :lock + -else + =link_to i(:pencil), edit_admin_p_document_path(p_document), :remote => true + + + - - -if false - %table - %tr - %td - Paid - %td - =p_document.paid - %tr - %td - TH Paid - %td - =p_document.theo_paid - -p_document.p_payment_documents.each do |pp| - %tr - %td - =pp.amount - %td - =pp.paid - =pp.p_payment.paid - - - - %td.actions - -if p_document.label == "Facture" and !@relances - -#if p_document.relative_docs.where(:label => "Avoir").count == 0 - =link_to "Créer un avoir", create_avoir_admin_p_document_path(p_document) #, :data => {:confirm => "Voulez-vous vraiment créer un avoir ?"} -    - \ No newline at end of file + \ No newline at end of file diff --git a/app/views/admin/p_documents/detail.html.haml b/app/views/admin/p_documents/detail.html.haml new file mode 100644 index 0000000..36b900e --- /dev/null +++ b/app/views/admin/p_documents/detail.html.haml @@ -0,0 +1,123 @@ +.qi_header + %h1 + Documents + %span + Détail document + + +.qi_row + .qi_pannel.qi_plain.padding + + =debug @p_document.save + =debug @p_document.totals + + =debug @p_document.paid_completed? + + -if false + =PDocument.where("cache_to_paid >= -1.0 and cache_to_paid <= 1.0 and paid = 0").all.count + -PDocument.where("cache_to_paid >= -1.0 and cache_to_paid <= 1.0 and paid = 0").all.each do |p_doc| + =p_doc.id + =p_doc.save + + + =#debug @p_document.save + + =debug @p_document.total_paid.to_f == @p_document.totals[:ok_total_ttc].to_f + =debug @p_document.total_paid.to_f + =debug @p_document.totals[:ok_total_ttc].to_f + + %table.en-tete-table{:style => "width:auto;"} + %tr + %th Date + %th N° Client + %th Type + %th Référence doc. + -if @p_document.cust_ref? + %th Réf. com. client + %th Total payé + %th Payée ? + %th Date paiement + %th Reste à payer + + + + %tr + + + %td{:style => "width:140px"} + =l @p_document.created_at, :format => :date #@p_document.created_at + + %td{:style => "width:70px"} + =@p_document.p_customer.code + + %td{:style => "width:110px"} + =@p_document.label + + %td{:style => "width:120px"} + =link_to @p_document.d_number, admin_p_document_path(@p_document.token) + + + -if @p_document.cust_ref? + %td{:style => "width:90px"} + =@p_document.cust_ref + + %td + =number_to_currency @p_document.total_paid.to_f + + %td{:style => "width:90px;font-size:3em;"} + =ic(:check) if @p_document.paid + %td + =l @p_document.paid_at, :format => :date if @p_document.paid_at + %td + =number_to_currency @p_document.cache_to_paid + + + + + %br + %br + =#render @p_document.arrondi if @p_document.arrondi + + %table.table + %tr + -if params[:p_payment_type_id].to_s != "" + %th + %th + %th Type de paiement + %th Date de paiement + %th Date théorique + + %th Client + %th Montant + %th Montant à affecter + %th + %th + %th + + + %tbody#p_payments_rows + =render @p_document.p_payments + + %p Affectations : + %table.table + %thead + %tr + %th ID + %th + Date + %th + Montant paiement total + + %th + Montant affecté à cette facture + + %th + + %tbody=render @p_document.p_payment_documents + + + + + + + \ No newline at end of file diff --git a/app/views/admin/p_documents/index.html.haml b/app/views/admin/p_documents/index.html.haml index 1e596f3..88c80c1 100644 --- a/app/views/admin/p_documents/index.html.haml +++ b/app/views/admin/p_documents/index.html.haml @@ -10,22 +10,22 @@ %table.table %tr - + %th Date - %th N° offre + %th Offre %th Client - %th Type %th Numéro %th Total HT %th Total TTC - -if params[:p_document_type_id].to_i == 4 - %th - Th. Payée - %th - Payée - - %th Etat + %th + Payée + %th Solde + %th Echéance + + %th Jours de retard + %th + diff --git a/app/views/admin/p_payment_documents/_p_payment_document.html.haml b/app/views/admin/p_payment_documents/_p_payment_document.html.haml new file mode 100644 index 0000000..a882d29 --- /dev/null +++ b/app/views/admin/p_payment_documents/_p_payment_document.html.haml @@ -0,0 +1,19 @@ +%tr + %td + =p_payment_document.id + + %td + =l p_payment_document.p_payment.paid_at + + + + %td + =number_to_currency p_payment_document.p_payment.amount + + %td + =number_to_currency p_payment_document.amount + + + %td.actions + =link_to i(:pencil), edit_admin_p_payment_path(p_payment_document.p_payment), :remote => true + \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index 10bd581..e3e5703 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -195,6 +195,7 @@ Rails.application.routes.draw do end member do + get :etat get :autocomplete_apercu end end diff --git a/db/migrate/20190320135017_create_p_compta_elements.rb b/db/migrate/20190320135017_create_p_compta_elements.rb new file mode 100644 index 0000000..2fb1a93 --- /dev/null +++ b/db/migrate/20190320135017_create_p_compta_elements.rb @@ -0,0 +1,14 @@ +class CreatePComptaElements < ActiveRecord::Migration + def change + create_table :p_compta_elements do |t| + t.string :element_type + t.integer :element_id + t.references :p_customer, index: true, foreign_key: true + t.datetime :date + t.decimal :amount, :precision => 13, :scale => 2 + t.boolean :solde, :default => false + + t.timestamps null: false + end + end +end diff --git a/db/migrate/20190627150811_add_other_caches_to_p_documents.rb b/db/migrate/20190627150811_add_other_caches_to_p_documents.rb new file mode 100644 index 0000000..a8becf6 --- /dev/null +++ b/db/migrate/20190627150811_add_other_caches_to_p_documents.rb @@ -0,0 +1,6 @@ +class AddOtherCachesToPDocuments < ActiveRecord::Migration + def change + add_column :p_documents, :cache_total_tva, :decimal, :precision => 13, :scale => 2 + add_column :p_documents, :cache_to_paid, :decimal, :precision => 13, :scale => 2 + end +end diff --git a/db/migrate/20190627165947_add_other_caches_to_p_customers.rb b/db/migrate/20190627165947_add_other_caches_to_p_customers.rb new file mode 100644 index 0000000..f9c3712 --- /dev/null +++ b/db/migrate/20190627165947_add_other_caches_to_p_customers.rb @@ -0,0 +1,6 @@ +class AddOtherCachesToPCustomers < ActiveRecord::Migration + def change + add_column :p_customers, :cache_payments, :decimal + add_column :p_customers, :cache_ca_ttc, :decimal + end +end diff --git a/db/schema.rb b/db/schema.rb index 8d6d12b..20fdf71 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20190312134247) do +ActiveRecord::Schema.define(version: 20190627165947) do create_table "admin_admin_roles", force: :cascade do |t| t.integer "admin_id", limit: 4 @@ -748,6 +748,19 @@ ActiveRecord::Schema.define(version: 20190312134247) do t.datetime "updated_at", null: false end + create_table "p_compta_elements", force: :cascade do |t| + t.string "element_type", limit: 255 + t.integer "element_id", limit: 4 + t.integer "p_customer_id", limit: 4 + t.datetime "date" + t.decimal "amount", precision: 13, scale: 2 + t.boolean "solde", default: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + + add_index "p_compta_elements", ["p_customer_id"], name: "index_p_compta_elements_on_p_customer_id", using: :btree + create_table "p_contact_contact_types", force: :cascade do |t| t.integer "p_contact_id", limit: 4 t.integer "p_contact_type_id", limit: 4 @@ -870,6 +883,8 @@ ActiveRecord::Schema.define(version: 20190312134247) do t.string "siret", limit: 255 t.string "ape", limit: 255 t.integer "p_payment_type_id", limit: 4 + t.decimal "cache_payments", precision: 10 + t.decimal "cache_ca_ttc", precision: 10 end add_index "p_customers", ["p_price_cat_id"], name: "index_p_customers_on_p_price_cat_id", using: :btree @@ -949,6 +964,8 @@ ActiveRecord::Schema.define(version: 20190312134247) do t.text "avoir_text", limit: 65535 t.string "doc_ref_number", limit: 255 t.decimal "cache_fdp", precision: 13, scale: 2 + t.decimal "cache_total_tva", precision: 13, scale: 2 + t.decimal "cache_to_paid", precision: 13, scale: 2 end create_table "p_eps", force: :cascade do |t| @@ -1013,7 +1030,7 @@ ActiveRecord::Schema.define(version: 20190312134247) do t.datetime "created_at", null: false t.datetime "updated_at", null: false t.integer "p_customer_id", limit: 4 - t.boolean "paid", default: false + t.boolean "paid", default: true t.boolean "canceled", default: false t.boolean "affected", default: false end @@ -1609,6 +1626,7 @@ ActiveRecord::Schema.define(version: 20190312134247) do add_foreign_key "menu_item_langs", "image_files" add_foreign_key "menu_item_langs", "lang_sites" add_foreign_key "p_box_fdps", "p_products" + add_foreign_key "p_compta_elements", "p_customers" add_foreign_key "p_contact_contact_types", "p_contact_types" add_foreign_key "p_contact_contact_types", "p_contacts" add_foreign_key "p_customer_sheets", "p_payment_types"