From ff76fa60c037dc5f5f69ee18f7677c5a723466d5 Mon Sep 17 00:00:00 2001 From: Patrick Gansterer Date: Fri, 1 Nov 2019 19:30:23 +0100 Subject: [PATCH] Allow deletion of financial transactions --- .../bootstrap_and_overrides.css.less | 4 ++++ .../financial_transactions_controller.rb | 7 +++++++ app/controllers/home_controller.rb | 2 +- app/models/financial_transaction.rb | 18 ++++++++++++++++++ app/models/ordergroup.rb | 7 +++++-- .../_transactions.html.haml | 12 +++++++++++- .../_transactions_search.html.haml | 5 +++++ .../financial_transactions/index.html.haml | 2 +- .../financial_transactions/index.js.erb | 2 +- app/views/home/index.html.haml | 2 +- config/locales/de.yml | 7 +++++++ config/locales/en.yml | 7 +++++++ ...dd_deleted_to_financial_transaction_type.rb | 8 ++++++++ db/schema.rb | 4 +++- 14 files changed, 79 insertions(+), 8 deletions(-) create mode 100644 db/migrate/20181201000200_add_deleted_to_financial_transaction_type.rb diff --git a/app/assets/stylesheets/bootstrap_and_overrides.css.less b/app/assets/stylesheets/bootstrap_and_overrides.css.less index 1c4c5681..cad8d6d3 100644 --- a/app/assets/stylesheets/bootstrap_and_overrides.css.less +++ b/app/assets/stylesheets/bootstrap_and_overrides.css.less @@ -537,3 +537,7 @@ span.positive_amount { span.negative_amout { color: red; } + +.deleted_row { + text-decoration: line-through; +} diff --git a/app/controllers/finance/financial_transactions_controller.rb b/app/controllers/finance/financial_transactions_controller.rb index 429bae1b..0fd4682e 100644 --- a/app/controllers/finance/financial_transactions_controller.rb +++ b/app/controllers/finance/financial_transactions_controller.rb @@ -21,6 +21,7 @@ class Finance::FinancialTransactionsController < ApplicationController @q = FinancialTransaction.search(params[:q]) @financial_transactions_all = @q.result(distinct: true).includes(:user).order(sort) + @financial_transactions_all = @financial_transactions_all.visible unless params[:show_hidden] @financial_transactions_all = @financial_transactions_all.where(ordergroup_id: @ordergroup.id) if @ordergroup @financial_transactions = @financial_transactions_all.page(params[:page]).per(@per_page) @@ -50,6 +51,12 @@ class Finance::FinancialTransactionsController < ApplicationController render :action => :new end + def destroy + transaction = FinancialTransaction.find(params[:id]) + transaction.revert!(current_user) + redirect_to finance_ordergroup_transactions_url(transaction.ordergroup), notice: t('finance.financial_transactions.controller.destroy.notice') + end + def new_collection end diff --git a/app/controllers/home_controller.rb b/app/controllers/home_controller.rb index b220d2b7..bdc89342 100644 --- a/app/controllers/home_controller.rb +++ b/app/controllers/home_controller.rb @@ -45,7 +45,7 @@ class HomeController < ApplicationController sort = "created_on DESC" end - @financial_transactions = @ordergroup.financial_transactions.page(params[:page]).per(@per_page).order(sort) + @financial_transactions = @ordergroup.financial_transactions.visible.page(params[:page]).per(@per_page).order(sort) @financial_transactions = @financial_transactions.where("note LIKE ?", "%#{params[:query]}%") if params[:query].present? else diff --git a/app/models/financial_transaction.rb b/app/models/financial_transaction.rb index 06454736..cea4be8d 100644 --- a/app/models/financial_transaction.rb +++ b/app/models/financial_transaction.rb @@ -5,11 +5,14 @@ class FinancialTransaction < ApplicationRecord belongs_to :user belongs_to :financial_link belongs_to :financial_transaction_type + belongs_to :reverts, class_name: 'FinancialTransaction', foreign_key: 'reverts_id' + has_one :reverted_by, class_name: 'FinancialTransaction', foreign_key: 'reverts_id' validates_presence_of :amount, :note, :user_id, :ordergroup_id validates_numericality_of :amount, greater_then: -100_000, less_than: 100_000 + scope :visible, -> { joins('LEFT JOIN financial_transactions r ON financial_transactions.id = r.reverts_id').where('r.id IS NULL').where(reverts: nil) } scope :without_financial_link, -> { where(financial_link: nil) } localize_input_of :amount @@ -23,6 +26,21 @@ class FinancialTransaction < ApplicationRecord ordergroup.add_financial_transaction! amount, note, user, financial_transaction_type end + def revert!(user) + transaction do + rt = dup + rt.amount = -rt.amount + rt.reverts = self + rt.user = user + rt.save! + ordergroup.update_balance! + end + end + + def hidden? + reverts.present? || reverted_by.present? + end + protected def initialize_financial_transaction_type diff --git a/app/models/ordergroup.rb b/app/models/ordergroup.rb index 1f98f8cd..ef6eed19 100644 --- a/app/models/ordergroup.rb +++ b/app/models/ordergroup.rb @@ -84,8 +84,7 @@ class Ordergroup < Group transaction do t = FinancialTransaction.new(ordergroup: self, amount: amount, note: note, user: user, financial_transaction_type: transaction_type, financial_link: link) t.save! - self.account_balance = financial_transactions.sum('amount') - save! + update_balance! # Notify only when order group had a positive balance before the last transaction: if t.amount < 0 && self.account_balance < 0 && self.account_balance - t.amount >= 0 Resque.enqueue(UserNotifier, FoodsoftConfig.scope, 'negative_balance', self.id, t.id) @@ -103,6 +102,10 @@ class Ordergroup < Group update_attribute(:stats, {:jobs_size => jobs, :orders_sum => orders_sum}) end + def update_balance! + update_attribute :account_balance, financial_transactions.sum('amount') + end + def avg_jobs_per_euro stats[:jobs_size].to_f / stats[:orders_sum].to_f rescue 0 end diff --git a/app/views/finance/financial_transactions/_transactions.html.haml b/app/views/finance/financial_transactions/_transactions.html.haml index dc99f65f..accbb0ce 100644 --- a/app/views/finance/financial_transactions/_transactions.html.haml +++ b/app/views/finance/financial_transactions/_transactions.html.haml @@ -1,4 +1,5 @@ - with_ordergroup = local_assigns[:with_ordergroup] +- with_hidden = local_assigns[:with_hidden] - with_csv = local_assigns[:with_csv] .pull-right - if with_csv @@ -22,9 +23,11 @@ - FinancialTransactionClass.sorted.each do |c| %th = sort_link_helper c.display, "amount" + - if with_hidden + %th %tbody - @financial_transactions.each do |t| - %tr + %tr{class: "#{'deleted_row' if t.hidden?}"} %td - if t.financial_link = link_to format_time(t.created_on), finance_link_path(t.financial_link) @@ -40,3 +43,10 @@ %td.numeric{style: 'width:5em'} - if t.financial_transaction_type.financial_transaction_class == c = format_currency t.amount + - if with_hidden + %td.actions{style: 'width:1em'} + - unless t.hidden? + = link_to finance_ordergroup_transaction_path(t.ordergroup, t), method: :delete, + data: {confirm: t('.confirm_revert', name: t.note)}, title: t('.revert_title'), + class: 'btn btn-danger btn-mini' do + = glyph :remove diff --git a/app/views/finance/financial_transactions/_transactions_search.html.haml b/app/views/finance/financial_transactions/_transactions_search.html.haml index 90ec796c..8af6a426 100644 --- a/app/views/finance/financial_transactions/_transactions_search.html.haml +++ b/app/views/finance/financial_transactions/_transactions_search.html.haml @@ -19,3 +19,8 @@ = f.text_field :amount_gteq, class: 'input-mini' %span.add-on - = f.text_field :amount_lteq, class: 'input-mini search-query' + +   + %label{for: 'show_hidden'} + = check_box_tag 'show_hidden', 1, params[:show_hidden] + = t '.show_hidden' diff --git a/app/views/finance/financial_transactions/index.html.haml b/app/views/finance/financial_transactions/index.html.haml index 584729cd..515d2fcc 100644 --- a/app/views/finance/financial_transactions/index.html.haml +++ b/app/views/finance/financial_transactions/index.html.haml @@ -22,4 +22,4 @@ = render 'transactions_search', url: finance_ordergroup_transactions_path(@ordergroup) -#transactions= render 'transactions', with_csv: true +#transactions= render 'transactions', with_csv: true, with_hidden: true diff --git a/app/views/finance/financial_transactions/index.js.erb b/app/views/finance/financial_transactions/index.js.erb index fdfe06a4..ae013f32 100644 --- a/app/views/finance/financial_transactions/index.js.erb +++ b/app/views/finance/financial_transactions/index.js.erb @@ -1 +1 @@ -$('#transactions').html('<%= escape_javascript(render("transactions", with_csv: true)) %>'); +$('#transactions').html('<%= escape_javascript(render("transactions", with_csv: true, with_hidden: true)) %>'); diff --git a/app/views/home/index.html.haml b/app/views/home/index.html.haml index 5e9c9122..9d1ee444 100644 --- a/app/views/home/index.html.haml +++ b/app/views/home/index.html.haml @@ -73,7 +73,7 @@ - FinancialTransactionClass.sorted.each do |fc| %th = fc.display - - for ft in current_user.ordergroup.financial_transactions.includes(:financial_transaction_type, :user).limit(5).order('created_on DESC') + - for ft in current_user.ordergroup.financial_transactions.visible.includes(:financial_transaction_type, :user).limit(5).order(created_on: :desc) %tr %td= format_time(ft.created_on) %td= h(show_user(ft.user)) diff --git a/config/locales/de.yml b/config/locales/de.yml index b2f722ba..2b77a081 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -825,6 +825,8 @@ de: alert: 'Ein Fehler ist aufgetreten: %{error}' error_note_required: Notiz wird benötigt! notice: Alle Transaktionen wurden gespeichert. + destroy: + notice: Transaktion wurde gelöscht index: balance: 'Kontostand: %{balance}' last_updated_at: "(zuletzt aktualisiert vor %{when})" @@ -847,6 +849,11 @@ de: ordergroup: remove: Entfernen remove_group: Gruppe enfernen + transactions: + confirm_revert: Wills du %{name} wirklich rückgängig machen? Hierbei wird eine zusätzliche Transaktion mit dem invertierten Betrag hinzugefügt und gemeinsam mit der originalen Transaktion versteckt. Diese versteckten Transaktionen sind nur über die Option 'Versteckte anzeigen' sichtbar und können von normalen Benutzer_innen überhaupt nicht angezeigt werden. + revert_title: Transaktion rückgängig machen, um sie vor normalen Benutzer_innen versteckt. + transactions_search: + show_hidden: Versteckte anzeigen index: amount_fc: Betrag(FC) end: Ende diff --git a/config/locales/en.yml b/config/locales/en.yml index 6add7be3..c259b78f 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -850,6 +850,8 @@ en: alert: 'An error occured: %{error}' error_note_required: Note is required! notice: All transactions were saved. + destroy: + notice: Transaktion wurde gelöscht index: balance: 'Balance of account: %{balance}' last_updated_at: "(last updated %{when} ago)" @@ -872,6 +874,11 @@ en: ordergroup: remove: Remove remove_group: Remove group + transactions: + confirm_revert: Do you really want to revert %{name}? In this case a new transaction with an inverted amount will be created and in combination with the original transaction hidden. These hidden transaction are only visibe via the 'Show hidden' option and are not visible to normal users at all. + revert_title: Revert the transaction, which will hide it from normal users. + transactions_search: + show_hidden: Show hidden transactions index: amount_fc: Amount(FC) end: End diff --git a/db/migrate/20181201000200_add_deleted_to_financial_transaction_type.rb b/db/migrate/20181201000200_add_deleted_to_financial_transaction_type.rb new file mode 100644 index 00000000..2a2a3b32 --- /dev/null +++ b/db/migrate/20181201000200_add_deleted_to_financial_transaction_type.rb @@ -0,0 +1,8 @@ +class AddDeletedToFinancialTransactionType < ActiveRecord::Migration + def change + change_table :financial_transactions do |t| + t.integer :reverts_id + t.index :reverts_id, unique: true + end + end +end diff --git a/db/schema.rb b/db/schema.rb index cf121eeb..f0038234 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: 20181201000100) do +ActiveRecord::Schema.define(version: 20181201000200) do create_table "article_categories", force: :cascade do |t| t.string "name", limit: 255, default: "", null: false @@ -136,9 +136,11 @@ ActiveRecord::Schema.define(version: 20181201000100) do t.datetime "created_on", null: false t.integer "financial_link_id" t.integer "financial_transaction_type_id", null: false + t.integer "reverts_id" end add_index "financial_transactions", ["ordergroup_id"], name: "index_financial_transactions_on_ordergroup_id", using: :btree + add_index "financial_transactions", ["reverts_id"], name: "index_financial_transactions_on_reverts_id", unique: true, using: :btree create_table "group_order_article_quantities", force: :cascade do |t| t.integer "group_order_article_id", limit: 4, default: 0, null: false