Evolutions sur les documents et export zip

This commit is contained in:
Nicolas VARROT 2016-09-27 11:36:13 +02:00
parent 5f8f037ab5
commit 26b2d81d74
25 changed files with 277 additions and 87 deletions

View File

@ -76,3 +76,6 @@ gem 'sidekiq'
gem "posix-spawn" gem "posix-spawn"
gem 'rubyzip', '>= 1.0.0' # will load new rubyzip version
gem 'zip-zip' # will load compatibility for old rubyzip API.

View File

@ -168,6 +168,7 @@ GEM
rmagick (2.13.4) rmagick (2.13.4)
ruby_parser (3.6.4) ruby_parser (3.6.4)
sexp_processor (~> 4.1) sexp_processor (~> 4.1)
rubyzip (1.2.0)
rvm-capistrano (1.4.1) rvm-capistrano (1.4.1)
capistrano (>= 2.0.0) capistrano (>= 2.0.0)
sass (3.4.12) sass (3.4.12)
@ -225,6 +226,8 @@ GEM
rails rails
wkhtmltopdf-binary (0.9.9.3) wkhtmltopdf-binary (0.9.9.3)
workflow (1.2.0) workflow (1.2.0)
zip-zip (0.3)
rubyzip (>= 1.0.0)
PLATFORMS PLATFORMS
ruby ruby
@ -251,6 +254,7 @@ DEPENDENCIES
posix-spawn posix-spawn
rails (= 4.2.0) rails (= 4.2.0)
rmagick rmagick
rubyzip (>= 1.0.0)
rvm-capistrano (= 1.4.1) rvm-capistrano (= 1.4.1)
sass-rails (~> 5.0) sass-rails (~> 5.0)
sdoc (~> 0.4.0) sdoc (~> 0.4.0)
@ -264,3 +268,4 @@ DEPENDENCIES
wicked_pdf wicked_pdf
wkhtmltopdf-binary wkhtmltopdf-binary
workflow (~> 1.2.0) workflow (~> 1.2.0)
zip-zip

View File

@ -107,6 +107,28 @@ class Admin::NeedsController < ApplicationController
redirect_to admin_needs_path redirect_to admin_needs_path
end 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 def validate
@need = Need.find(params[:id]) @need = Need.find(params[:id])
if @need.validate! if @need.validate!

View File

@ -118,6 +118,107 @@ class Admin::OffersController < ApplicationController
@offer = Offer.find(params[:id]) @offer = Offer.find(params[:id])
end 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

60
app/controllers/public/documents_controller.rb Normal file → Executable file
View File

@ -4,7 +4,12 @@ class Public::DocumentsController < ApplicationController
before_filter :auth_customer before_filter :auth_customer
before_filter :check_enabled 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 def index
@ -12,12 +17,10 @@ class Public::DocumentsController < ApplicationController
end end
def download def download
if !params[:admin] @document = Document.find_by_download_token!(params[:download_token])
@document = @accepted_offer.documents.find(params[:id])
else
@document = Document.find(params[:id])
end
if !params[:admin] if !params[:admin]
if @document.state == 'document_available' if @document.state == 'document_available'
@document.state = :document_downloaded @document.state = :document_downloaded
@ -30,44 +33,10 @@ class Public::DocumentsController < ApplicationController
end end
end end
if @document.particulars 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' send_data @document.get_particularized_document_file , :filename =>"negos-document-#{@document.id}.pdf" , :type => 'application/pdf',:disposition => (params[:inline] ? 'inline' : "attachment")
::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")
@ -125,14 +94,5 @@ class Public::DocumentsController < ApplicationController
end 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 end

View File

@ -3,6 +3,9 @@ class Document < ActiveRecord::Base
belongs_to :accepted_offer belongs_to :accepted_offer
before_create :generate_download_token
before_create :set_default_fields_values
has_one :customer, :through => :accepted_offer has_one :customer, :through => :accepted_offer
mount_uploader :document, DocumentUploader mount_uploader :document, DocumentUploader
@ -60,4 +63,55 @@ class Document < ActiveRecord::Base
end end
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 end

View File

@ -62,10 +62,13 @@ class Need < ActiveRecord::Base
event :negociate, :transitions_to => :negociating event :negociate, :transitions_to => :negociating
end end
state :negociating do state :negociating do
event :back_to_verified, :transitions_to => :verified
event :accept, :transitions_to => :negociated event :accept, :transitions_to => :negociated
event :reject, :transitions_to => :failed event :reject, :transitions_to => :failed
end end
state :negociated state :negociated do
event :back_to_negociating, :transitions_to => :negociating
end
state :failed state :failed
end end
@ -112,6 +115,15 @@ class Need < ActiveRecord::Base
end end
end end
def back_to_verified
end
def back_to_negociating
end
# Human state conversion # Human state conversion

View File

@ -45,7 +45,7 @@
= file_field_tag :document = file_field_tag :document
= submit_tag("Charger" , class:"btn btn-primary") = submit_tag("Charger" , class:"btn btn-primary")
-else -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? -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é ?'} =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é ?'}

View File

@ -27,7 +27,10 @@
-if(need.verified?) -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'} = 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?) -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-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'} = 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(:"trash"), [:admin, need], :data => {:confirm => 'Voulez-vous vraiment supprimer ce besoin ?'}, :method => :delete
= link_to i(:pencil), edit_admin_need_path(need) = link_to i(:pencil), edit_admin_need_path(need)

View File

@ -26,7 +26,7 @@
Créé Créé
%th{style: 'text-align:center' } %th{style: 'text-align:center' }
Commentaires/Intérêts Commentaires/Intérêts
%th{:style => "width:100px"} %th{:style => "width:200px"}
&nbsp; &nbsp;
%tbody.rows %tbody.rows
@ -58,7 +58,7 @@
Propositions Propositions
%th %th
Statut Statut
%th{:style => "width:100px"} %th{:style => "width:200px"}
&nbsp; &nbsp;
%tbody.rows %tbody.rows

View File

@ -25,6 +25,13 @@
=@offer.supplier =@offer.supplier
</strong> </strong>
%br %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 %table.table.admin-table.table-hover.table-striped
%thead.rows_header %thead.rows_header
%tr %tr

View File

@ -0,0 +1,20 @@
%h1
= "Charger un document pour toutes les offres acceptées du besoin "
<strong>
= @offer.need.title
</strong>
=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"}

4
app/views/public/documents/_document.html.haml Normal file → Executable file
View File

@ -3,13 +3,13 @@
= i(:file) + " " + document.title = i(:file) + " " + document.title
%td{style:"text-align:center"} %td{style:"text-align:center"}
-if document.document? -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 -else
Pas encore disponible Pas encore disponible
%td{style:"text-align:center"} %td{style:"text-align:center"}
-if !document.not_available? -if !document.not_available?
-if !document.returned_document? -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 %span.btn.btn-default.btn-file
="Ouvrir (PDF)" ="Ouvrir (PDF)"
= file_field_tag :returned_document = file_field_tag :returned_document

View File

@ -20,11 +20,8 @@ Rails.application.routes.draw do
get 'p/:mlm_token' => "public/customers#parrainage", :as => :mlm_token get 'p/:mlm_token' => "public/customers#parrainage", :as => :mlm_token
namespace :public do namespace :public do
resources :documents do
member do get 'documents/:download_token', to: 'documents#download', as: :download_document
get :download
end
end
resources :customer_favs resources :customer_favs
@ -298,6 +295,8 @@ Rails.application.routes.draw do
get :negociate get :negociate
get :accept get :accept
get :reject get :reject
get :back_to_verified
get :back_to_negociating
end end
end end
@ -322,16 +321,14 @@ Rails.application.routes.draw do
get :force_verified get :force_verified
end end
member do member do
get :validate_all_documents get :validate_all_documents
end end
end end
member do member do
get :download_zip
get :upload_documents
post :upload_documents
get :accepted get :accepted
end end
end end

View File

0
db/migrate/20160317170901_add_note_field_to_need.rb Normal file → Executable file
View File

View File

0
db/migrate/20160413101451_add_last_activity_to_user.rb Normal file → Executable file
View File

0
db/migrate/20160530173603_create_domains.rb Normal file → Executable file
View File

0
db/migrate/20160530173749_create_domain_needs.rb Normal file → Executable file
View File

0
db/migrate/20160530173923_create_domain_customers.rb Normal file → Executable file
View File

View File

View File

View File

@ -0,0 +1,5 @@
class AddDownloadTokenToDocuments < ActiveRecord::Migration
def change
add_column :documents, :download_token, :string
end
end

View File

@ -11,7 +11,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # 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| create_table "accepted_offers", force: :cascade do |t|
t.datetime "created_at", null: false t.datetime "created_at", null: false
@ -248,6 +248,7 @@ ActiveRecord::Schema.define(version: 20160920185645) do
t.datetime "created_at", null: false t.datetime "created_at", null: false
t.datetime "updated_at", null: false t.datetime "updated_at", null: false
t.boolean "particulars", limit: 1 t.boolean "particulars", limit: 1
t.string "download_token", limit: 255
end end
create_table "domain_customers", force: :cascade do |t| create_table "domain_customers", force: :cascade do |t|