From 709b10eb13ae386a667fbdfccff8188dfe11b7d2 Mon Sep 17 00:00:00 2001 From: Patrick Gansterer Date: Fri, 6 Mar 2020 12:28:54 +0100 Subject: [PATCH] Add attachment to user --- app/controllers/admin/users_controller.rb | 7 ++++ app/models/concerns/attachment.rb | 32 +++++++++++++++++++ app/models/invoice.rb | 28 +--------------- app/models/user.rb | 1 + app/views/admin/users/_form.html.haml | 3 ++ app/views/admin/users/show.html.haml | 3 ++ config/locales/de.yml | 6 ++-- config/locales/en.yml | 6 ++-- config/locales/es.yml | 7 ++-- config/locales/fr.yml | 2 ++ config/locales/nl.yml | 6 ++-- config/routes.rb | 1 + .../20181206000000_add_attachment_to_user.rb | 6 ++++ db/schema.rb | 4 ++- 14 files changed, 76 insertions(+), 36 deletions(-) create mode 100644 app/models/concerns/attachment.rb create mode 100644 db/migrate/20181206000000_add_attachment_to_user.rb diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb index d4e2b78a5..e7efce185 100644 --- a/app/controllers/admin/users_controller.rb +++ b/app/controllers/admin/users_controller.rb @@ -32,4 +32,11 @@ def sudo login @user redirect_to root_path, notice: I18n.t('admin.users.controller.sudo_done', user: @user.name) end + + def attachment + @user = User.find(params[:id]) + type = MIME::Types[@user.attachment_mime].first + filename = "user_#{@user.id}_attachment.#{type.preferred_extension}" + send_data @user.attachment_data, filename: filename, type: type + end end diff --git a/app/models/concerns/attachment.rb b/app/models/concerns/attachment.rb new file mode 100644 index 000000000..a2b3d198f --- /dev/null +++ b/app/models/concerns/attachment.rb @@ -0,0 +1,32 @@ +module Attachment + extend ActiveSupport::Concern + + included do + validate :valid_attachment + attr_accessor :delete_attachment + + def attachment=(incoming_file) + self.attachment_data = incoming_file.read + # allow to soft-fail when FileMagic isn't present and removed from Gemfile (e.g. Heroku) + self.attachment_mime = defined?(FileMagic) ? FileMagic.new(FileMagic::MAGIC_MIME).buffer(self.attachment_data) : 'application/octet-stream' + end + + def delete_attachment=(value) + if ActiveRecord::Type::Boolean.new.type_cast_from_user(value) + self.attachment_data = nil + self.attachment_mime = nil + end + end + + protected + + def valid_attachment + if attachment_data + mime = MIME::Type.simplified(attachment_mime) + unless %w(application/pdf image/jpeg).include? mime + errors.add :attachment, I18n.t('model.invalid_mime', mime: mime) + end + end + end + end +end diff --git a/app/models/invoice.rb b/app/models/invoice.rb index c102a3ea7..1e133cdff 100644 --- a/app/models/invoice.rb +++ b/app/models/invoice.rb @@ -1,4 +1,5 @@ class Invoice < ApplicationRecord + include Attachment include CustomFields belongs_to :supplier @@ -9,29 +10,13 @@ class Invoice < ApplicationRecord validates_presence_of :supplier_id validates_numericality_of :amount, :deposit, :deposit_credit - validate :valid_attachment scope :unpaid, -> { where(paid_on: nil) } scope :without_financial_link, -> { where(financial_link: 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 - # allow to soft-fail when FileMagic isn't present and removed from Gemfile (e.g. Heroku) - self.attachment_mime = defined?(FileMagic) ? FileMagic.new(FileMagic::MAGIC_MIME).buffer(self.attachment_data) : 'application/octet-stream' - 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.try(:id) == user.id) end @@ -40,15 +25,4 @@ def user_can_edit?(user) 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/models/user.rb b/app/models/user.rb index a7c5c6b8c..897b67074 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -3,6 +3,7 @@ require 'digest/sha1' # specific user rights through memberships (see Group) class User < ApplicationRecord + include Attachment include CustomFields #TODO: acts_as_paraniod ?? diff --git a/app/views/admin/users/_form.html.haml b/app/views/admin/users/_form.html.haml index 563414a75..6096e7c56 100644 --- a/app/views/admin/users/_form.html.haml +++ b/app/views/admin/users/_form.html.haml @@ -1,5 +1,8 @@ = simple_form_for([:admin, @user]) do |f| = render 'shared/user_form_fields', f: f, password_autocomplete: false + = f.input :attachment, as: :file, hint: t('.attachment_hint') + - if f.object.attachment_data.present? + = f.input :delete_attachment, as: :boolean = f.input :send_welcome_mail, as: :boolean, label: false, inline_label: t('.send_welcome_mail') - unless @user.ordergroup = f.input :create_ordergroup, as: :boolean, label: false, inline_label: t('.create_ordergroup') diff --git a/app/views/admin/users/show.html.haml b/app/views/admin/users/show.html.haml index a9c25c41f..8d7dd9208 100644 --- a/app/views/admin/users/show.html.haml +++ b/app/views/admin/users/show.html.haml @@ -18,6 +18,9 @@ = link_to t('.show_email_problems'), admin_mail_delivery_status_index_path(email: @user.email), class: 'btn btn-warning btn-mini' %dt= heading_helper User, :phone %dd= @user.phone + - if @user.attachment_data + %dt= heading_helper User, :attachment + %dd= link_to t('ui.download'), admin_user_attachment_path(@user) %dt= heading_helper User, :last_login %dd= format_time(@user.last_login) %dt= heading_helper User, :last_activity diff --git a/config/locales/de.yml b/config/locales/de.yml index f53c950c4..0300d5ff0 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -187,6 +187,8 @@ de: user_list: Verantwortlichen workgroup: Arbeitsgruppe user: + attachment: Anhang + delete_attachment: Anhang löschen email: E-Mail first_name: Vorname iban: IBAN @@ -347,6 +349,7 @@ de: edit: title: Benutzer/in bearbeiten form: + attachment_hint: Es sind nur JPEG und PDF erlaubt. create_ordergroup: Bestellgruppe mit dem selben Namen erstellen und Benutzer_in hinzufügen. send_welcome_mail: Eine Willkommen-Nachricht an Benutzer_in senden. index: @@ -1311,8 +1314,7 @@ de: no_delete_last: Es muss mindestens ein Kontotransaktionstyp existieren. group_order: stock_ordergroup_name: Lager (%{user}) - invoice: - invalid_mime: hat einen ungültigen MIME-Typ (%{mime}) + invalid_mime: hat einen ungültigen MIME-Typ (%{mime}) membership: no_admin_delete: Mitgliedschaft kann nicht beendet werden. Du bist die letzte Administratorin order_article: diff --git a/config/locales/en.yml b/config/locales/en.yml index 5ba3055c8..debc4e64c 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -198,6 +198,8 @@ en: user_list: Responsible users workgroup: Workgroup user: + attachment: Attachment + delete_attachment: Delete attachment email: Email first_name: First name iban: IBAN @@ -363,6 +365,7 @@ en: edit: title: Edit user form: + attachment_hint: Only JPEG and PDF are allowed. create_ordergroup: Create ordergroup with the same name and add user. send_welcome_mail: Send a welcome mail to the user. index: @@ -1350,8 +1353,7 @@ en: no_delete_last: At least one financial transaction type must exist. group_order: stock_ordergroup_name: Stock (%{user}) - invoice: - invalid_mime: has an invalid MIME type (%{mime}) + invalid_mime: has an invalid MIME type (%{mime}) membership: no_admin_delete: Membership can not be withdrawn as you are the last administrator. order_article: diff --git a/config/locales/es.yml b/config/locales/es.yml index d3c8662d3..6d6499e9a 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -155,6 +155,8 @@ es: user_list: Usuarios responsables workgroup: Grupo de trabajo user: + attachment: Adjunto + delete_attachment: Borra adjunto first_name: Nombre last_activity: Última actividad last_login: Último login @@ -287,6 +289,8 @@ es: notice: El usuario/a ha sido borrado edit: title: Edita usuario/a + form: + attachment_hint: Sólo se permiten los formatos JPEG y PDF. index: first_paragraph: Aquí puedes %{url}, editar y borar usuarios. new_user: Crea nuevo usuario/a @@ -1096,8 +1100,7 @@ es: model: delivery: each_stock_article_must_be_unique: Los artículos de stock no pueden ser listados más de una vez. - invoice: - invalid_mime: tiene un tipo de MIME inválido (%{mime}) + invalid_mime: tiene un tipo de MIME inválido (%{mime}) membership: no_admin_delete: No te puedes salir de este grupo porque eres el último adimistrador/a. user: diff --git a/config/locales/fr.yml b/config/locales/fr.yml index d048b7bfd..ffc54afd7 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -138,6 +138,8 @@ fr: user_list: Responsables inscritEs workgroup: Équipe user: + attachment: Appendice + delete_attachment: Supprimer appendice first_name: Prénom last_activity: dernière activité last_login: Dernière connection diff --git a/config/locales/nl.yml b/config/locales/nl.yml index 5ed255dfa..db07dc289 100644 --- a/config/locales/nl.yml +++ b/config/locales/nl.yml @@ -190,6 +190,8 @@ nl: user_list: Verantwoordelijken workgroup: Werkgroep user: + attachment: Bijlage + delete_attachment: Verwijder bijlage email: Email first_name: Voornaam iban: IBAN @@ -354,6 +356,7 @@ nl: edit: title: Lid bewerken form: + attachment_hint: Alleen JPEG en PDF zijn toegestaan. create_ordergroup: Maak een huishouden met dezelfde naam en voeg een gebruiker toe. index: first_paragraph: Hier kun je gebruikers %{url}, bewerken en wissen. @@ -1301,8 +1304,7 @@ nl: no_delete_last: Er moet ten minste één financiëel transactie type bestaan. group_order: stock_ordergroup_name: Voorraad (%{user}) - invoice: - invalid_mime: heeft ongeldig MIME type (%{mime}) + invalid_mime: heeft ongeldig MIME type (%{mime}) membership: no_admin_delete: Lidmaatschap kan niet beeindigd worden. Je bent de laatste administrator. order_article: diff --git a/config/routes.rb b/config/routes.rb index 912c807ea..0187e5059 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -234,6 +234,7 @@ resources :financial_transaction_types resources :users do + get :attachment, on: :member post :restore, on: :member post :sudo, on: :member end diff --git a/db/migrate/20181206000000_add_attachment_to_user.rb b/db/migrate/20181206000000_add_attachment_to_user.rb new file mode 100644 index 000000000..789fcb1e8 --- /dev/null +++ b/db/migrate/20181206000000_add_attachment_to_user.rb @@ -0,0 +1,6 @@ +class AddAttachmentToUser < ActiveRecord::Migration + def change + add_column :users, :attachment_mime, :string + add_column :users, :attachment_data, :binary, :limit => 8.megabyte + end +end diff --git a/db/schema.rb b/db/schema.rb index fea4e4403..defe39eca 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: 20181205010000) do +ActiveRecord::Schema.define(version: 20181206000000) do create_table "article_categories", force: :cascade do |t| t.string "name", limit: 255, default: "", null: false @@ -552,6 +552,8 @@ t.datetime "last_activity" t.datetime "deleted_at" t.string "iban", limit: 255 + t.string "attachment_mime", limit: 255 + t.binary "attachment_data", limit: 16777215 end add_index "users", ["email"], name: "index_users_on_email", unique: true, using: :btree