From 749791bb7aa99de23cba0ac4698b52f00686e5ab Mon Sep 17 00:00:00 2001 From: Patrick Gansterer Date: Fri, 6 May 2016 15:04:58 +0200 Subject: [PATCH] Add possibility to add an attachment to an invoice #345 --- .travis.yml | 3 +- Gemfile | 1 + Gemfile.lock | 2 ++ .../finance/invoices_controller.rb | 7 +++++ app/models/invoice.rb | 28 +++++++++++++++++++ app/views/finance/invoices/_form.html.haml | 2 ++ app/views/finance/invoices/show.html.haml | 4 +++ config/locales/de.yml | 7 +++++ config/locales/en.yml | 7 +++++ config/locales/fr.yml | 3 ++ config/locales/nl.yml | 3 ++ config/routes.rb | 1 + ...0160218151041_add_attachment_to_invoice.rb | 6 ++++ db/schema.rb | 2 ++ 14 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 db/migrate/20160218151041_add_attachment_to_invoice.rb diff --git a/.travis.yml b/.travis.yml index 4864223d..95301c80 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,12 +1,13 @@ language: ruby sudo: false -rvm: +rvm: - 2.1 services: - redis-server addons: apt: packages: + - libmagic-dev - metacity env: COVERALLS=1 before_install: diff --git a/Gemfile b/Gemfile index f398f4c5..55a4c32f 100644 --- a/Gemfile +++ b/Gemfile @@ -46,6 +46,7 @@ gem 'roo', '~> 2.0.0' gem 'roo-xls' gem 'spreadsheet' gem 'gaffe' +gem 'ruby-filemagic' # we use the git version of acts_as_versioned, and need to include it in this Gemfile gem 'acts_as_versioned', github: 'technoweenie/acts_as_versioned' diff --git a/Gemfile.lock b/Gemfile.lock index d8053ccb..d27253b5 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -359,6 +359,7 @@ GEM rspec-rerun (1.1.0) rspec (~> 3.0) rspec-support (3.4.1) + ruby-filemagic (0.7.1) ruby-ole (1.2.12) ruby-prof (0.15.9) ruby-units (2.0.0) @@ -519,6 +520,7 @@ DEPENDENCIES rspec-core (~> 3.2) rspec-rails rspec-rerun + ruby-filemagic ruby-prof ruby-units sass-rails diff --git a/app/controllers/finance/invoices_controller.rb b/app/controllers/finance/invoices_controller.rb index c2f7f6e9..3c2da9d8 100644 --- a/app/controllers/finance/invoices_controller.rb +++ b/app/controllers/finance/invoices_controller.rb @@ -62,6 +62,13 @@ class Finance::InvoicesController < ApplicationController redirect_to finance_invoices_url end + def attachment + @invoice = Invoice.find(params[:invoice_id]) + type = MIME::Types[@invoice.attachment_mime].first + filename = "invoice_#{@invoice.id}_attachment.#{type.preferred_extension}" + send_data(@invoice.attachment_data, :filename => filename, :type => type) + end + private def find_invoice diff --git a/app/models/invoice.rb b/app/models/invoice.rb index 3f910f80..d0a6fabf 100644 --- a/app/models/invoice.rb +++ b/app/models/invoice.rb @@ -1,3 +1,5 @@ +require 'filemagic' + class Invoice < ActiveRecord::Base belongs_to :supplier @@ -7,12 +9,27 @@ class Invoice < ActiveRecord::Base validates_presence_of :supplier_id validates_numericality_of :amount, :deposit, :deposit_credit + validate :valid_attachment scope :unpaid, -> { where(paid_on: nil) } + attr_accessor :delete_attachment + # Replace numeric seperator with database format localize_input_of :amount, :deposit, :deposit_credit + def attachment=(incoming_file) + self.attachment_data = incoming_file.read + self.attachment_mime = FileMagic.new(FileMagic::MAGIC_MIME).buffer(self.attachment_data) + end + + def delete_attachment=(value) + if value == '1' + self.attachment_data = nil + self.attachment_mime = nil + end + end + def user_can_edit?(user) user.role_finance? || (user.role_invoices? && !self.paid_on && self.created_by.id == user.id) end @@ -21,4 +38,15 @@ class Invoice < ActiveRecord::Base def net_amount amount - deposit + deposit_credit end + + protected + + def valid_attachment + if attachment_data + mime = MIME::Type.simplified(attachment_mime) + unless ['application/pdf', 'image/jpeg'].include? mime + errors.add :attachment, I18n.t('model.invoice.invalid_mime', :mime => mime) + end + end + end end diff --git a/app/views/finance/invoices/_form.html.haml b/app/views/finance/invoices/_form.html.haml index eb879bce..c130a954 100644 --- a/app/views/finance/invoices/_form.html.haml +++ b/app/views/finance/invoices/_form.html.haml @@ -22,6 +22,8 @@ = f.input :amount, as: :string = f.input :deposit, as: :string = f.input :deposit_credit, as: :string + = f.input :attachment, as: :file, hint: t('.attachment_hint') + = f.input :delete_attachment, as: :boolean = f.input :note .form-actions = f.submit class: 'btn' diff --git a/app/views/finance/invoices/show.html.haml b/app/views/finance/invoices/show.html.haml index ccb87778..067b0396 100644 --- a/app/views/finance/invoices/show.html.haml +++ b/app/views/finance/invoices/show.html.haml @@ -58,6 +58,10 @@ %p %b= heading_helper(Invoice, :total) + ':' = number_to_currency total +%p + %b= heading_helper(Invoice, :attachment) + ':' + - if @invoice.attachment_data + = link_to t('ui.download'), finance_invoice_attachment_path(@invoice) %p %b= heading_helper(Invoice, :note) + ':' =h @invoice.note diff --git a/config/locales/de.yml b/config/locales/de.yml index 7128c274..5db31b15 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -54,9 +54,11 @@ de: total_price: Summe invoice: amount: Betrag + attachment: Anhang created_at: Erstellt am created_by: Erstellt von date: Rechnungsdatum + delete_attachment: Anhang löschen deliveries: Lieferung deposit: Pfand berechnet deposit_credit: Pfand gutgeschrieben @@ -779,6 +781,8 @@ de: invoices: edit: title: Rechnung bearbeiten + form: + attachment_hint: Es sind nur JPEG und PDF erlaubt. index: action_new: Neue Rechnung anlegen title: Rechnungen @@ -1175,6 +1179,8 @@ de: stock_ordergroup_name: Lager (%{user}) membership: no_admin_delete: Mitgliedschaft kann nicht beendet werden. Du bist die letzte Administratorin + invoice: + invalid_mime: hat einen ungültigen MIME-Typ (%{mime}) order_article: error_price: muss angegeben sein und einen aktuellen Preis haben page: @@ -1704,6 +1710,7 @@ de: confirm_restore: Willst du %{name} wirklich wiederherstellen? copy: Kopieren delete: Löschen + download: Herunterladen edit: Bearbeiten marks: close: "×" diff --git a/config/locales/en.yml b/config/locales/en.yml index e8db8367..8de63cd6 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -54,9 +54,11 @@ en: total_price: Sum invoice: amount: Amount + attachment: Attachment created_at: Created at created_by: Created by date: Billing date + delete_attachment: Delete attachment deliveries: Delivery deposit: Deposit charged deposit_credit: Deposit returned @@ -793,6 +795,8 @@ en: invoices: edit: title: Edit invoice + form: + attachment_hint: Only JPEG and PDF are allowed. index: action_new: Create new invoice title: Invoices @@ -1196,6 +1200,8 @@ en: stock_ordergroup_name: Stock (%{user}) membership: no_admin_delete: Membership can not be withdrawn as you are the last administrator. + invoice: + invalid_mime: has an invalide MIME type (%{mime}) order_article: error_price: must be specified and have a current price price page: @@ -1727,6 +1733,7 @@ en: confirm_restore: Do you really want to restore %{name}? copy: Copy delete: Delete + download: Download edit: Edit marks: close: "×" diff --git a/config/locales/fr.yml b/config/locales/fr.yml index 322ae0a1..9bc2e1a8 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -54,9 +54,11 @@ fr: total_price: Total invoice: amount: Montant + attachment: Appendice created_at: Créé le created_by: "Établi par" date: Date de facturation + delete_attachment: Supprimer appendice deliveries: Réapprovisionnement deposit: Consigne facturée deposit_credit: Consigne remboursée @@ -1705,6 +1707,7 @@ fr: confirm_delete: Veux-tu vraiment supprimer %{name}? copy: delete: Supprimer + download: Télécharger edit: Modifier marks: close: "×" diff --git a/config/locales/nl.yml b/config/locales/nl.yml index a4eb7400..638942eb 100644 --- a/config/locales/nl.yml +++ b/config/locales/nl.yml @@ -54,9 +54,11 @@ nl: total_price: Som invoice: amount: Bedrag + attachment: Bijlage created_at: Gemaakt op created_by: Gemaakt door date: Factuurdatum + delete_attachment: Verwijder bijlage deliveries: Levering deposit: Statiegeld in rekening gebracht deposit_credit: Statiegeld teruggekregen @@ -1692,6 +1694,7 @@ nl: confirm_delete: Wil je %{name} daadwerkelijk wissen? copy: Kopiëren delete: Verwijder + download: Downloaden edit: Bewerk marks: close: "×" diff --git a/config/routes.rb b/config/routes.rb index 147bab13..e135002b 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -157,6 +157,7 @@ Foodsoft::Application.routes.draw do end resources :invoices do + get :attachment get :form_on_supplier_id_change, on: :collection end diff --git a/db/migrate/20160218151041_add_attachment_to_invoice.rb b/db/migrate/20160218151041_add_attachment_to_invoice.rb new file mode 100644 index 00000000..0c76e75d --- /dev/null +++ b/db/migrate/20160218151041_add_attachment_to_invoice.rb @@ -0,0 +1,6 @@ +class AddAttachmentToInvoice < ActiveRecord::Migration + def change + add_column :invoices, :attachment_mime, :string + add_column :invoices, :attachment_data, :binary, :limit => 8.megabyte + end +end diff --git a/db/schema.rb b/db/schema.rb index 6f00ff8a..76e5e310 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -169,6 +169,8 @@ ActiveRecord::Schema.define(version: 20160226000000) do t.datetime "created_at" t.datetime "updated_at" t.integer "created_by_user_id" + t.string "attachment_mime" + t.binary "attachment_data" end add_index "invoices", ["supplier_id"], name: "index_invoices_on_supplier_id", using: :btree