Add possibility to add an attachment to an invoice #345

This commit is contained in:
Patrick Gansterer 2016-05-06 15:04:58 +02:00
parent 8d5467ab7c
commit 749791bb7a
14 changed files with 75 additions and 1 deletions

View file

@ -7,6 +7,7 @@ services:
addons: addons:
apt: apt:
packages: packages:
- libmagic-dev
- metacity - metacity
env: COVERALLS=1 env: COVERALLS=1
before_install: before_install:

View file

@ -46,6 +46,7 @@ gem 'roo', '~> 2.0.0'
gem 'roo-xls' gem 'roo-xls'
gem 'spreadsheet' gem 'spreadsheet'
gem 'gaffe' gem 'gaffe'
gem 'ruby-filemagic'
# we use the git version of acts_as_versioned, and need to include it in this Gemfile # 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' gem 'acts_as_versioned', github: 'technoweenie/acts_as_versioned'

View file

@ -359,6 +359,7 @@ GEM
rspec-rerun (1.1.0) rspec-rerun (1.1.0)
rspec (~> 3.0) rspec (~> 3.0)
rspec-support (3.4.1) rspec-support (3.4.1)
ruby-filemagic (0.7.1)
ruby-ole (1.2.12) ruby-ole (1.2.12)
ruby-prof (0.15.9) ruby-prof (0.15.9)
ruby-units (2.0.0) ruby-units (2.0.0)
@ -519,6 +520,7 @@ DEPENDENCIES
rspec-core (~> 3.2) rspec-core (~> 3.2)
rspec-rails rspec-rails
rspec-rerun rspec-rerun
ruby-filemagic
ruby-prof ruby-prof
ruby-units ruby-units
sass-rails sass-rails

View file

@ -62,6 +62,13 @@ class Finance::InvoicesController < ApplicationController
redirect_to finance_invoices_url redirect_to finance_invoices_url
end 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 private
def find_invoice def find_invoice

View file

@ -1,3 +1,5 @@
require 'filemagic'
class Invoice < ActiveRecord::Base class Invoice < ActiveRecord::Base
belongs_to :supplier belongs_to :supplier
@ -7,12 +9,27 @@ class Invoice < ActiveRecord::Base
validates_presence_of :supplier_id validates_presence_of :supplier_id
validates_numericality_of :amount, :deposit, :deposit_credit validates_numericality_of :amount, :deposit, :deposit_credit
validate :valid_attachment
scope :unpaid, -> { where(paid_on: nil) } scope :unpaid, -> { where(paid_on: nil) }
attr_accessor :delete_attachment
# Replace numeric seperator with database format # Replace numeric seperator with database format
localize_input_of :amount, :deposit, :deposit_credit 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) def user_can_edit?(user)
user.role_finance? || (user.role_invoices? && !self.paid_on && self.created_by.id == user.id) user.role_finance? || (user.role_invoices? && !self.paid_on && self.created_by.id == user.id)
end end
@ -21,4 +38,15 @@ class Invoice < ActiveRecord::Base
def net_amount def net_amount
amount - deposit + deposit_credit amount - deposit + deposit_credit
end 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 end

View file

@ -22,6 +22,8 @@
= f.input :amount, as: :string = f.input :amount, as: :string
= f.input :deposit, as: :string = f.input :deposit, as: :string
= f.input :deposit_credit, 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 = f.input :note
.form-actions .form-actions
= f.submit class: 'btn' = f.submit class: 'btn'

View file

@ -58,6 +58,10 @@
%p %p
%b= heading_helper(Invoice, :total) + ':' %b= heading_helper(Invoice, :total) + ':'
= number_to_currency 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 %p
%b= heading_helper(Invoice, :note) + ':' %b= heading_helper(Invoice, :note) + ':'
=h @invoice.note =h @invoice.note

View file

@ -54,9 +54,11 @@ de:
total_price: Summe total_price: Summe
invoice: invoice:
amount: Betrag amount: Betrag
attachment: Anhang
created_at: Erstellt am created_at: Erstellt am
created_by: Erstellt von created_by: Erstellt von
date: Rechnungsdatum date: Rechnungsdatum
delete_attachment: Anhang löschen
deliveries: Lieferung deliveries: Lieferung
deposit: Pfand berechnet deposit: Pfand berechnet
deposit_credit: Pfand gutgeschrieben deposit_credit: Pfand gutgeschrieben
@ -779,6 +781,8 @@ de:
invoices: invoices:
edit: edit:
title: Rechnung bearbeiten title: Rechnung bearbeiten
form:
attachment_hint: Es sind nur JPEG und PDF erlaubt.
index: index:
action_new: Neue Rechnung anlegen action_new: Neue Rechnung anlegen
title: Rechnungen title: Rechnungen
@ -1175,6 +1179,8 @@ de:
stock_ordergroup_name: Lager (%{user}) stock_ordergroup_name: Lager (%{user})
membership: membership:
no_admin_delete: Mitgliedschaft kann nicht beendet werden. Du bist die letzte Administratorin 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: order_article:
error_price: muss angegeben sein und einen aktuellen Preis haben error_price: muss angegeben sein und einen aktuellen Preis haben
page: page:
@ -1704,6 +1710,7 @@ de:
confirm_restore: Willst du %{name} wirklich wiederherstellen? confirm_restore: Willst du %{name} wirklich wiederherstellen?
copy: Kopieren copy: Kopieren
delete: Löschen delete: Löschen
download: Herunterladen
edit: Bearbeiten edit: Bearbeiten
marks: marks:
close: "&times;" close: "&times;"

View file

@ -54,9 +54,11 @@ en:
total_price: Sum total_price: Sum
invoice: invoice:
amount: Amount amount: Amount
attachment: Attachment
created_at: Created at created_at: Created at
created_by: Created by created_by: Created by
date: Billing date date: Billing date
delete_attachment: Delete attachment
deliveries: Delivery deliveries: Delivery
deposit: Deposit charged deposit: Deposit charged
deposit_credit: Deposit returned deposit_credit: Deposit returned
@ -793,6 +795,8 @@ en:
invoices: invoices:
edit: edit:
title: Edit invoice title: Edit invoice
form:
attachment_hint: Only JPEG and PDF are allowed.
index: index:
action_new: Create new invoice action_new: Create new invoice
title: Invoices title: Invoices
@ -1196,6 +1200,8 @@ en:
stock_ordergroup_name: Stock (%{user}) stock_ordergroup_name: Stock (%{user})
membership: membership:
no_admin_delete: Membership can not be withdrawn as you are the last administrator. 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: order_article:
error_price: must be specified and have a current price price error_price: must be specified and have a current price price
page: page:
@ -1727,6 +1733,7 @@ en:
confirm_restore: Do you really want to restore %{name}? confirm_restore: Do you really want to restore %{name}?
copy: Copy copy: Copy
delete: Delete delete: Delete
download: Download
edit: Edit edit: Edit
marks: marks:
close: "&times;" close: "&times;"

View file

@ -54,9 +54,11 @@ fr:
total_price: Total total_price: Total
invoice: invoice:
amount: Montant amount: Montant
attachment: Appendice
created_at: Créé le created_at: Créé le
created_by: "Établi par" created_by: "Établi par"
date: Date de facturation date: Date de facturation
delete_attachment: Supprimer appendice
deliveries: Réapprovisionnement deliveries: Réapprovisionnement
deposit: Consigne facturée deposit: Consigne facturée
deposit_credit: Consigne remboursée deposit_credit: Consigne remboursée
@ -1705,6 +1707,7 @@ fr:
confirm_delete: Veux-tu vraiment supprimer %{name}? confirm_delete: Veux-tu vraiment supprimer %{name}?
copy: copy:
delete: Supprimer delete: Supprimer
download: Télécharger
edit: Modifier edit: Modifier
marks: marks:
close: "&times;" close: "&times;"

View file

@ -54,9 +54,11 @@ nl:
total_price: Som total_price: Som
invoice: invoice:
amount: Bedrag amount: Bedrag
attachment: Bijlage
created_at: Gemaakt op created_at: Gemaakt op
created_by: Gemaakt door created_by: Gemaakt door
date: Factuurdatum date: Factuurdatum
delete_attachment: Verwijder bijlage
deliveries: Levering deliveries: Levering
deposit: Statiegeld in rekening gebracht deposit: Statiegeld in rekening gebracht
deposit_credit: Statiegeld teruggekregen deposit_credit: Statiegeld teruggekregen
@ -1692,6 +1694,7 @@ nl:
confirm_delete: Wil je %{name} daadwerkelijk wissen? confirm_delete: Wil je %{name} daadwerkelijk wissen?
copy: Kopiëren copy: Kopiëren
delete: Verwijder delete: Verwijder
download: Downloaden
edit: Bewerk edit: Bewerk
marks: marks:
close: "&times;" close: "&times;"

View file

@ -157,6 +157,7 @@ Foodsoft::Application.routes.draw do
end end
resources :invoices do resources :invoices do
get :attachment
get :form_on_supplier_id_change, on: :collection get :form_on_supplier_id_change, on: :collection
end end

View file

@ -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

View file

@ -169,6 +169,8 @@ ActiveRecord::Schema.define(version: 20160226000000) do
t.datetime "created_at" t.datetime "created_at"
t.datetime "updated_at" t.datetime "updated_at"
t.integer "created_by_user_id" t.integer "created_by_user_id"
t.string "attachment_mime"
t.binary "attachment_data"
end end
add_index "invoices", ["supplier_id"], name: "index_invoices_on_supplier_id", using: :btree add_index "invoices", ["supplier_id"], name: "index_invoices_on_supplier_id", using: :btree