diff --git a/Gemfile b/Gemfile index d19b77c..93ff100 100755 --- a/Gemfile +++ b/Gemfile @@ -75,4 +75,7 @@ gem 'workflow', '~> 1.2.0' gem 'sidekiq' -gem "posix-spawn" \ No newline at end of file +gem "posix-spawn" + +gem 'rubyzip', '>= 1.0.0' # will load new rubyzip version +gem 'zip-zip' # will load compatibility for old rubyzip API. diff --git a/Gemfile.lock b/Gemfile.lock index 342955c..6e00749 100755 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -168,6 +168,7 @@ GEM rmagick (2.13.4) ruby_parser (3.6.4) sexp_processor (~> 4.1) + rubyzip (1.2.0) rvm-capistrano (1.4.1) capistrano (>= 2.0.0) sass (3.4.12) @@ -225,6 +226,8 @@ GEM rails wkhtmltopdf-binary (0.9.9.3) workflow (1.2.0) + zip-zip (0.3) + rubyzip (>= 1.0.0) PLATFORMS ruby @@ -251,6 +254,7 @@ DEPENDENCIES posix-spawn rails (= 4.2.0) rmagick + rubyzip (>= 1.0.0) rvm-capistrano (= 1.4.1) sass-rails (~> 5.0) sdoc (~> 0.4.0) @@ -264,3 +268,4 @@ DEPENDENCIES wicked_pdf wkhtmltopdf-binary workflow (~> 1.2.0) + zip-zip diff --git a/app/controllers/admin/needs_controller.rb b/app/controllers/admin/needs_controller.rb index cf31ff5..08a077e 100755 --- a/app/controllers/admin/needs_controller.rb +++ b/app/controllers/admin/needs_controller.rb @@ -107,6 +107,28 @@ class Admin::NeedsController < ApplicationController redirect_to admin_needs_path end + + def back_to_verified + @need = Need.find(params[:id]) + if @need.back_to_verified! + flash[:notice] = "Besoin repositionné à l'état vérifié" + else + flash[:error] = "L'état actuel de ce besoin ne permet pas ce changement d'état" + end + redirect_to admin_needs_path + end + + def back_to_negociating + @need = Need.find(params[:id]) + if @need.back_to_negociating! + flash[:notice] = "Besoin repositionné à l'état de négociation en cours" + else + flash[:error] = "L'état actuel de ce besoin ne permet pas ce changement d'état" + end + redirect_to admin_needs_path + end + + def validate @need = Need.find(params[:id]) if @need.validate! diff --git a/app/controllers/admin/offers_controller.rb b/app/controllers/admin/offers_controller.rb index 3d2645d..1eb5ff7 100755 --- a/app/controllers/admin/offers_controller.rb +++ b/app/controllers/admin/offers_controller.rb @@ -118,6 +118,107 @@ class Admin::OffersController < ApplicationController @offer = Offer.find(params[:id]) end + def download_zip + @offer = Offer.find(params[:id]) + + + + zipfile_name = "#{Rails.root}/private_medias/zip/tmp_zip.zip" + csvfile_name = "#{Rails.root}/private_medias/zip/tmp_csv.csv" + + File.delete(zipfile_name) if File.exist?(zipfile_name) + File.delete(csvfile_name) if File.exist?(csvfile_name) + + Zip::File.open(zipfile_name, Zip::File::CREATE) do |zipfile| + + @offer.accepted_offers.each do |accepted_offer| + + customer_name = "#{accepted_offer.customer.organisation} (#{accepted_offer.customer.firstname} #{accepted_offer.customer.name})" + + accepted_offer.documents.each do |document| + + document_name = document.title + + + if document.document.file + if document.particulars? + zipfile.add("#{customer_name}/#{document_name}/#{document.title}-NÉGOS.pdf", document.get_particularized_document_file.path) + else + zipfile.add("#{customer_name}/#{document_name}/#{document.title}-NÉGOS.pdf", document.document.current_path) + end + end + + if document.returned_document.file + zipfile.add("#{customer_name}/#{document_name}/#{document.title}-RETOURNÉ.pdf", document.returned_document.current_path) + end + end + + end + + CSV.open(csvfile_name, "wb",headers: true, :col_sep => ";" ) do |csv| + csv << ["Société", "prénom", "nom", "Téléphone","Email","Offres acceptée?", "Acceptée le", "Intéressé le"].map{|row| row.encode("iso-8859-1")} + @offer.need.wishes.each do |wish| + accepted_offer = @offer.accepted_offers.where(customer_id: wish.customer.id).first + if accepted_offer + accepted = true + else + accepted = false + end + csv << [ + wish.customer.organisation ? wish.customer.organisation : "Aucune", + wish.customer.firstname, + wish.customer.name, + wish.customer.phone, + wish.customer.email, + accepted ? "Oui" : "Non", + accepted ? accepted_offer.updated_at.to_s : "", + wish.updated_at.to_s + ].map{|row| row.encode("iso-8859-1")} + end + + + end + + zipfile.add("Utilisateurs intéressés.csv", csvfile_name) + + end + + + + filename = "[Besoin:#{@offer.need.title}][Offre:#{@offer.supplier}] Export des documents fait le #{DateTime.now.to_time.strftime('%d/%m/%y')}.zip" + + send_file(zipfile_name, :filename => filename) + #File.delete(zipfile_name) + + end + + def upload_documents + @offer = Offer.find(params[:id]) + + if request.post? + + counter = 0 + @offer.accepted_offers.each do |accepted_offer| + document = Document.new + document.title = params[:document][:title] + document.document = params[:document][:document] + document.accepted_offer = accepted_offer + + if params[:document][:document] + document.state = "document_available" + end + + document.save + CustomerMailer.document_available(accepted_offer.customer, document).deliver + counter = counter + 1 + end + + flash[:notice] = "#{counter} document(s) créé(s)" + redirect_to accepted_admin_offer_path(@offer) + end + + end + diff --git a/app/controllers/public/documents_controller.rb b/app/controllers/public/documents_controller.rb old mode 100644 new mode 100755 index 256c293..34e24f6 --- a/app/controllers/public/documents_controller.rb +++ b/app/controllers/public/documents_controller.rb @@ -4,7 +4,12 @@ class Public::DocumentsController < ApplicationController before_filter :auth_customer before_filter :check_enabled - before_filter :check_owner + before_filter :load_accepted_offer, except: [:download] + + + def load_accepted_offer + @accepted_offer = AcceptedOffer.find(params[:accepted_offer_id]) + end def index @@ -12,12 +17,10 @@ class Public::DocumentsController < ApplicationController end + def download - if !params[:admin] - @document = @accepted_offer.documents.find(params[:id]) - else - @document = Document.find(params[:id]) - end + @document = Document.find_by_download_token!(params[:download_token]) + if !params[:admin] if @document.state == 'document_available' @document.state = :document_downloaded @@ -30,49 +33,15 @@ class Public::DocumentsController < ApplicationController end end if @document.particulars - @temp_file = "#{Rails.root}/pdf/documents/#{@document.id}_temp.pdf" - @final_file = "#{Rails.root}/pdf/documents/#{@document.id}.pdf" - @final_file2 = "#{Rails.root}/pdf/documents/#{@document.id}-2.pdf" - - - view = ActionView::Base.new(Rails.root.join('app/views')) - view.class.include ApplicationHelper - view.class.include Rails.application.routes.url_helpers - pdf = view.render( - :pdf => "#{@document.id}", - :template => "public/documents/particulars.html.haml", - - :locals => {:@document => @document}) - - # then save to a file - pdf = WickedPdf.new.pdf_from_string(pdf, :margin => { top: 0, # default 10 (mm) - bottom: 0, - left: 0, - right: 0 }) - save_path = @temp_file - File.open(save_path, 'wb') do |file| - file << pdf - end - - - - require 'posix/spawn' - - ::POSIX::Spawn::Child.new 'pdftk', @document.document.file.path, 'background',@temp_file , 'output', @final_file - - ::POSIX::Spawn::Child.new 'pdftk', "A="+@document.document.file.path, 'B='+@final_file ,"cat", "B1", "A2-end", 'output', @final_file2 - - - @data_to_send = File.open( @final_file2).read - - send_data @data_to_send, :filename =>"negos-document-#{@document.id}.pdf" , :type => 'application/pdf',:disposition => (params[:inline] ? 'inline' : "attachment") - - - - - + + send_data @document.get_particularized_document_file , :filename =>"negos-document-#{@document.id}.pdf" , :type => 'application/pdf',:disposition => (params[:inline] ? 'inline' : "attachment") + + + + + #render :inline => "j" else send_file @document.document.file.path @@ -125,14 +94,5 @@ class Public::DocumentsController < ApplicationController end - def check_owner - if !params[:admin] - @accepted_offer = AcceptedOffer.find(params[:accepted_offer_id]) - if @accepted_offer.customer.id != current_customer.id - flash[:error] = "Vous n'avez pas la permission d'accéder à cette page" - redirect_back_or_default :root - end - end - end end diff --git a/app/models/document.rb b/app/models/document.rb index 16b8102..a3a945a 100755 --- a/app/models/document.rb +++ b/app/models/document.rb @@ -2,7 +2,10 @@ class Document < ActiveRecord::Base include Workflow belongs_to :accepted_offer - + + before_create :generate_download_token + before_create :set_default_fields_values + has_one :customer, :through => :accepted_offer mount_uploader :document, DocumentUploader @@ -60,4 +63,55 @@ class Document < ActiveRecord::Base end end + def generate_download_token + self.download_token = loop do + download_token = SecureRandom.urlsafe_base64(nil, false) + break download_token unless Document.exists?(download_token: download_token) + end + end + + def set_default_fields_values + self.particulars = true + end + + + def get_particularized_document_file + @temp_file = "#{Rails.root}/pdf/documents/#{self.id}_temp.pdf" + @final_file = "#{Rails.root}/pdf/documents/#{self.id}.pdf" + @final_file2 = "#{Rails.root}/pdf/documents/#{self.id}-2.pdf" + + + view = ActionView::Base.new(Rails.root.join('app/views')) + view.class.include ApplicationHelper + view.class.include Rails.application.routes.url_helpers + + pdf = view.render( + :pdf => "#{self.id}", + :template => "public/documents/particulars.html.haml", + + :locals => {:@document => self}) + + # then save to a file + pdf = WickedPdf.new.pdf_from_string(pdf, :margin => { top: 0, # default 10 (mm) + bottom: 0, + left: 0, + right: 0 }) + + save_path = @temp_file + File.open(save_path, 'wb') do |file| + file << pdf + end + + + + require 'posix/spawn' + + ::POSIX::Spawn::Child.new 'pdftk', self.document.file.path, 'background',@temp_file , 'output', @final_file + + ::POSIX::Spawn::Child.new 'pdftk', "A="+self.document.file.path, 'B='+@final_file ,"cat", "B1", "A2-end", 'output', @final_file2 + + + @data_to_send = File.open( @final_file2).read + end + end diff --git a/app/models/need.rb b/app/models/need.rb index e6a2351..e591df0 100755 --- a/app/models/need.rb +++ b/app/models/need.rb @@ -8,9 +8,9 @@ class Need < ActiveRecord::Base scope :shared, -> { where(state: ["verified", "negociating", "negociated", "failed"]) } - - - + + + scope :with_wishes_count, -> { joins('left join wishes on wishes.need_id = needs.id') .select('needs.*, count(wishes.id) as wishes_count') @@ -25,12 +25,12 @@ class Need < ActiveRecord::Base scope :search, -> (search) { where('needs.title LIKE ? OR needs.description LIKE ?', "%#{search}%", "%#{search}%") } - + scope :domain_in, -> (domain_ids) { joins(:domains).where('domains.id IN(?)', domain_ids) } - - + + after_create :create @@ -62,10 +62,13 @@ class Need < ActiveRecord::Base event :negociate, :transitions_to => :negociating end state :negociating do + event :back_to_verified, :transitions_to => :verified event :accept, :transitions_to => :negociated event :reject, :transitions_to => :failed end - state :negociated + state :negociated do + event :back_to_negociating, :transitions_to => :negociating + end state :failed end @@ -112,6 +115,15 @@ class Need < ActiveRecord::Base end end + def back_to_verified + + end + + def back_to_negociating + + end + + # Human state conversion diff --git a/app/views/admin/accepted_offers/show.html.haml b/app/views/admin/accepted_offers/show.html.haml index eb26b8d..717b61a 100755 --- a/app/views/admin/accepted_offers/show.html.haml +++ b/app/views/admin/accepted_offers/show.html.haml @@ -45,7 +45,7 @@ = file_field_tag :document = submit_tag("Charger" , class:"btn btn-primary") -else - =link_to i(:"download"), download_public_document_path(document, :admin => true),title: "Télécharger le document" + =link_to i(:"download"),public_download_document_path(document.download_token, admin: true),title: "Télécharger le document" -if !document.document_verified? =link_to i(:"remove"), admin_offer_accepted_offer_document_delete_path(@offer, @accepted_offer, document), title: "Supprimer le fichier chargé", :data => {:confirm => 'Voulez-vous vraiment supprimer le fichier chargé ?'} @@ -71,9 +71,9 @@ %td{style:"text-align:right"} -if !document.document_verified? =link_to i(:"check"), admin_offer_accepted_offer_document_force_verified_path(@offer, @accepted_offer, document), title: "Marquer ce document comme vérifié", :data => {:confirm => 'Voulez-vous vraiment marquer ce document comme vérifié ?'} - + =link_to i(:"pencil"), edit_admin_document_path(document), :remote => true - + =link_to i(:"trash"), admin_offer_accepted_offer_document_destroy_path(@offer, @accepted_offer, document), title: "Supprimer le document", :data => {:confirm => 'Voulez-vous vraiment supprimer ce document ?'} -if @accepted_offer.waiting_documents? && @accepted_offer.documents.where(state: :document_verified).count == @accepted_offer.documents.count diff --git a/app/views/admin/needs/_need.html.haml b/app/views/admin/needs/_need.html.haml index 6309b64..570e9a3 100755 --- a/app/views/admin/needs/_need.html.haml +++ b/app/views/admin/needs/_need.html.haml @@ -27,7 +27,10 @@ -if(need.verified?) = link_to i(:"comments"), negociate_admin_need_path(need), title: "Passer en négociation", :data => {:confirm => 'Voulez-vous vraiment passer ce besoin en négociation'} -if(need.negociating?) + = link_to i(:"arrow-left"), back_to_verified_admin_need_path(need), title: "Revenir à l'état \"vérifié\"", :data => {:confirm => "Voulez-vous vraiment revnir à l'état \"vérifié\""} = link_to i(:"thumbs-up"), accept_admin_need_path(need), title: "Passer en négocié et créer une proposition", :data => {:confirm => 'Voulez-vous vraiment passer ce besoin en négocié ?'} = link_to i(:"thumbs-down"), reject_admin_need_path(need), title: "Passer en négociation échouée", :data => {:confirm => 'Voulez-vous vraiment passer ce besoin en négociation échouée'} + -if(need.negociated?) + = link_to i(:"arrow-left"), back_to_negociating_admin_need_path(need), title: "Revenir à l'état \"Négociation en cours...\"", :data => {:confirm => "Voulez-vous vraiment revnir à l'état \"Négociation en cours...\""} = link_to i(:"trash"), [:admin, need], :data => {:confirm => 'Voulez-vous vraiment supprimer ce besoin ?'}, :method => :delete = link_to i(:pencil), edit_admin_need_path(need) diff --git a/app/views/admin/needs/index.html.haml b/app/views/admin/needs/index.html.haml index 42bb49c..e6355ba 100755 --- a/app/views/admin/needs/index.html.haml +++ b/app/views/admin/needs/index.html.haml @@ -26,7 +26,7 @@ Créé %th{style: 'text-align:center' } Commentaires/Intérêts - %th{:style => "width:100px"} + %th{:style => "width:200px"}   %tbody.rows @@ -58,7 +58,7 @@ Propositions %th Statut - %th{:style => "width:100px"} + %th{:style => "width:200px"}   %tbody.rows diff --git a/app/views/admin/offers/accepted.html.haml b/app/views/admin/offers/accepted.html.haml index 0086b1c..29f30a2 100755 --- a/app/views/admin/offers/accepted.html.haml +++ b/app/views/admin/offers/accepted.html.haml @@ -25,6 +25,13 @@ =@offer.supplier %br + +%div{style:"display-block"} + + =link_to ic(:"upload") + " Charger un document pour toutes les offres acceptées", upload_documents_admin_offer_path, class: "btn btn-primary",style:{display: "inline-block"} + =link_to ic(:"download") + " Télécharger le zip de l'offre", download_zip_admin_offer_path, class: "btn btn-primary",style:{display: "inline-block"} +%br + %table.table.admin-table.table-hover.table-striped %thead.rows_header %tr diff --git a/app/views/admin/offers/upload_documents.haml b/app/views/admin/offers/upload_documents.haml new file mode 100755 index 0000000..e49396f --- /dev/null +++ b/app/views/admin/offers/upload_documents.haml @@ -0,0 +1,20 @@ +%h1 + = "Charger un document pour toutes les offres acceptées du besoin " + + = @offer.need.title + + + +=semantic_form_for :document do |f| + .content + + =f.inputs do + =f.input :title, :label => "Titre du document : " + =f.input :document, :label => "Le document (PDF) : ", as: :file + + + + %div{style:"display-block"} + + =link_to ic(:"chevron-circle-left") + " Retour", accepted_admin_offer_path(@offer), class: "btn btn-default",style:{display: "inline-block"} + =f.submit "Créer le document sur toutes les offres acceptées", :class => "btn btn-primary", style:{display: "inline-block"} diff --git a/app/views/public/documents/_document.html.haml b/app/views/public/documents/_document.html.haml old mode 100644 new mode 100755 index 3fc743d..a188e6d --- a/app/views/public/documents/_document.html.haml +++ b/app/views/public/documents/_document.html.haml @@ -3,13 +3,13 @@ = i(:file) + " " + document.title %td{style:"text-align:center"} -if document.document? - =link_to ic(:download), download_public_accepted_offer_document_path(@accepted_offer, document),class: "btn btn-primary btn-sm",title: "Télécharger le document" + =link_to ic(:download), public_download_document_path(document.download_token),class: "btn btn-primary btn-sm",title: "Télécharger le document" -else Pas encore disponible %td{style:"text-align:center"} -if !document.not_available? -if !document.returned_document? - = form_tag upload_returned_public_accepted_offer_document_path(@accepted_offer, document), name: :returned_document, method: :post, multipart: true do + = form_tag public_download_document_path(document.download_token), name: :returned_document, method: :post, multipart: true do %span.btn.btn-default.btn-file ="Ouvrir (PDF)" = file_field_tag :returned_document diff --git a/config/routes.rb b/config/routes.rb index 4d1f930..f6ba520 100755 --- a/config/routes.rb +++ b/config/routes.rb @@ -20,13 +20,10 @@ Rails.application.routes.draw do get 'p/:mlm_token' => "public/customers#parrainage", :as => :mlm_token namespace :public do - resources :documents do - member do - get :download - end - end - - + + get 'documents/:download_token', to: 'documents#download', as: :download_document + + resources :customer_favs resources :customer_ribs do @@ -230,9 +227,9 @@ Rails.application.routes.draw do end namespace :admin do - + resources :documents - + resources :domains resources :annonces do @@ -298,6 +295,8 @@ Rails.application.routes.draw do get :negociate get :accept get :reject + get :back_to_verified + get :back_to_negociating end end @@ -322,16 +321,14 @@ Rails.application.routes.draw do get :force_verified end member do - - get :validate_all_documents - - end end - member do + get :download_zip + get :upload_documents + post :upload_documents get :accepted end end diff --git a/db/migrate/20160317130441_add_image_and_file_to_need.rb b/db/migrate/20160317130441_add_image_and_file_to_need.rb old mode 100644 new mode 100755 diff --git a/db/migrate/20160317170901_add_note_field_to_need.rb b/db/migrate/20160317170901_add_note_field_to_need.rb old mode 100644 new mode 100755 diff --git a/db/migrate/20160318165409_add_devis_and_note_to_wish.rb b/db/migrate/20160318165409_add_devis_and_note_to_wish.rb old mode 100644 new mode 100755 diff --git a/db/migrate/20160413101451_add_last_activity_to_user.rb b/db/migrate/20160413101451_add_last_activity_to_user.rb old mode 100644 new mode 100755 diff --git a/db/migrate/20160530173603_create_domains.rb b/db/migrate/20160530173603_create_domains.rb old mode 100644 new mode 100755 diff --git a/db/migrate/20160530173749_create_domain_needs.rb b/db/migrate/20160530173749_create_domain_needs.rb old mode 100644 new mode 100755 diff --git a/db/migrate/20160530173923_create_domain_customers.rb b/db/migrate/20160530173923_create_domain_customers.rb old mode 100644 new mode 100755 diff --git a/db/migrate/20160530213935_create_domain_need_categories.rb b/db/migrate/20160530213935_create_domain_need_categories.rb old mode 100644 new mode 100755 diff --git a/db/migrate/20160920185645_add_particulars_to_documents.rb b/db/migrate/20160920185645_add_particulars_to_documents.rb old mode 100644 new mode 100755 diff --git a/db/migrate/20160926090902_add_download_token_to_documents.rb b/db/migrate/20160926090902_add_download_token_to_documents.rb new file mode 100755 index 0000000..b1eb84b --- /dev/null +++ b/db/migrate/20160926090902_add_download_token_to_documents.rb @@ -0,0 +1,5 @@ +class AddDownloadTokenToDocuments < ActiveRecord::Migration + def change + add_column :documents, :download_token, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index e583399..0eb9936 100755 --- 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: 20160920185645) do +ActiveRecord::Schema.define(version: 20160926090902) do create_table "accepted_offers", force: :cascade do |t| t.datetime "created_at", null: false @@ -248,6 +248,7 @@ ActiveRecord::Schema.define(version: 20160920185645) do t.datetime "created_at", null: false t.datetime "updated_at", null: false t.boolean "particulars", limit: 1 + t.string "download_token", limit: 255 end create_table "domain_customers", force: :cascade do |t|