Allow deletion of financial transactions

This commit is contained in:
Patrick Gansterer 2019-11-01 19:30:23 +01:00
parent 260ef90f6b
commit ff76fa60c0
14 changed files with 79 additions and 8 deletions

View file

@ -537,3 +537,7 @@ span.positive_amount {
span.negative_amout { span.negative_amout {
color: red; color: red;
} }
.deleted_row {
text-decoration: line-through;
}

View file

@ -21,6 +21,7 @@ class Finance::FinancialTransactionsController < ApplicationController
@q = FinancialTransaction.search(params[:q]) @q = FinancialTransaction.search(params[:q])
@financial_transactions_all = @q.result(distinct: true).includes(:user).order(sort) @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_all = @financial_transactions_all.where(ordergroup_id: @ordergroup.id) if @ordergroup
@financial_transactions = @financial_transactions_all.page(params[:page]).per(@per_page) @financial_transactions = @financial_transactions_all.page(params[:page]).per(@per_page)
@ -50,6 +51,12 @@ class Finance::FinancialTransactionsController < ApplicationController
render :action => :new render :action => :new
end 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 def new_collection
end end

View file

@ -45,7 +45,7 @@ class HomeController < ApplicationController
sort = "created_on DESC" sort = "created_on DESC"
end 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? @financial_transactions = @financial_transactions.where("note LIKE ?", "%#{params[:query]}%") if params[:query].present?
else else

View file

@ -5,11 +5,14 @@ class FinancialTransaction < ApplicationRecord
belongs_to :user belongs_to :user
belongs_to :financial_link belongs_to :financial_link
belongs_to :financial_transaction_type 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_presence_of :amount, :note, :user_id, :ordergroup_id
validates_numericality_of :amount, greater_then: -100_000, validates_numericality_of :amount, greater_then: -100_000,
less_than: 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) } scope :without_financial_link, -> { where(financial_link: nil) }
localize_input_of :amount localize_input_of :amount
@ -23,6 +26,21 @@ class FinancialTransaction < ApplicationRecord
ordergroup.add_financial_transaction! amount, note, user, financial_transaction_type ordergroup.add_financial_transaction! amount, note, user, financial_transaction_type
end 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 protected
def initialize_financial_transaction_type def initialize_financial_transaction_type

View file

@ -84,8 +84,7 @@ class Ordergroup < Group
transaction do transaction do
t = FinancialTransaction.new(ordergroup: self, amount: amount, note: note, user: user, financial_transaction_type: transaction_type, financial_link: link) t = FinancialTransaction.new(ordergroup: self, amount: amount, note: note, user: user, financial_transaction_type: transaction_type, financial_link: link)
t.save! t.save!
self.account_balance = financial_transactions.sum('amount') update_balance!
save!
# Notify only when order group had a positive balance before the last transaction: # 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 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) 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}) update_attribute(:stats, {:jobs_size => jobs, :orders_sum => orders_sum})
end end
def update_balance!
update_attribute :account_balance, financial_transactions.sum('amount')
end
def avg_jobs_per_euro def avg_jobs_per_euro
stats[:jobs_size].to_f / stats[:orders_sum].to_f rescue 0 stats[:jobs_size].to_f / stats[:orders_sum].to_f rescue 0
end end

View file

@ -1,4 +1,5 @@
- with_ordergroup = local_assigns[:with_ordergroup] - with_ordergroup = local_assigns[:with_ordergroup]
- with_hidden = local_assigns[:with_hidden]
- with_csv = local_assigns[:with_csv] - with_csv = local_assigns[:with_csv]
.pull-right .pull-right
- if with_csv - if with_csv
@ -22,9 +23,11 @@
- FinancialTransactionClass.sorted.each do |c| - FinancialTransactionClass.sorted.each do |c|
%th %th
= sort_link_helper c.display, "amount" = sort_link_helper c.display, "amount"
- if with_hidden
%th
%tbody %tbody
- @financial_transactions.each do |t| - @financial_transactions.each do |t|
%tr %tr{class: "#{'deleted_row' if t.hidden?}"}
%td %td
- if t.financial_link - if t.financial_link
= link_to format_time(t.created_on), finance_link_path(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'} %td.numeric{style: 'width:5em'}
- if t.financial_transaction_type.financial_transaction_class == c - if t.financial_transaction_type.financial_transaction_class == c
= format_currency t.amount = 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

View file

@ -19,3 +19,8 @@
= f.text_field :amount_gteq, class: 'input-mini' = f.text_field :amount_gteq, class: 'input-mini'
%span.add-on - %span.add-on -
= f.text_field :amount_lteq, class: 'input-mini search-query' = f.text_field :amount_lteq, class: 'input-mini search-query'
&nbsp;
%label{for: 'show_hidden'}
= check_box_tag 'show_hidden', 1, params[:show_hidden]
= t '.show_hidden'

View file

@ -22,4 +22,4 @@
= render 'transactions_search', url: finance_ordergroup_transactions_path(@ordergroup) = render 'transactions_search', url: finance_ordergroup_transactions_path(@ordergroup)
#transactions= render 'transactions', with_csv: true #transactions= render 'transactions', with_csv: true, with_hidden: true

View file

@ -1 +1 @@
$('#transactions').html('<%= escape_javascript(render("transactions", with_csv: true)) %>'); $('#transactions').html('<%= escape_javascript(render("transactions", with_csv: true, with_hidden: true)) %>');

View file

@ -73,7 +73,7 @@
- FinancialTransactionClass.sorted.each do |fc| - FinancialTransactionClass.sorted.each do |fc|
%th %th
= fc.display = 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 %tr
%td= format_time(ft.created_on) %td= format_time(ft.created_on)
%td= h(show_user(ft.user)) %td= h(show_user(ft.user))

View file

@ -825,6 +825,8 @@ de:
alert: 'Ein Fehler ist aufgetreten: %{error}' alert: 'Ein Fehler ist aufgetreten: %{error}'
error_note_required: Notiz wird benötigt! error_note_required: Notiz wird benötigt!
notice: Alle Transaktionen wurden gespeichert. notice: Alle Transaktionen wurden gespeichert.
destroy:
notice: Transaktion wurde gelöscht
index: index:
balance: 'Kontostand: %{balance}' balance: 'Kontostand: %{balance}'
last_updated_at: "(zuletzt aktualisiert vor %{when})" last_updated_at: "(zuletzt aktualisiert vor %{when})"
@ -847,6 +849,11 @@ de:
ordergroup: ordergroup:
remove: Entfernen remove: Entfernen
remove_group: Gruppe enfernen 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: index:
amount_fc: Betrag(FC) amount_fc: Betrag(FC)
end: Ende end: Ende

View file

@ -850,6 +850,8 @@ en:
alert: 'An error occured: %{error}' alert: 'An error occured: %{error}'
error_note_required: Note is required! error_note_required: Note is required!
notice: All transactions were saved. notice: All transactions were saved.
destroy:
notice: Transaktion wurde gelöscht
index: index:
balance: 'Balance of account: %{balance}' balance: 'Balance of account: %{balance}'
last_updated_at: "(last updated %{when} ago)" last_updated_at: "(last updated %{when} ago)"
@ -872,6 +874,11 @@ en:
ordergroup: ordergroup:
remove: Remove remove: Remove
remove_group: Remove group 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: index:
amount_fc: Amount(FC) amount_fc: Amount(FC)
end: End end: End

View file

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

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: 20181201000100) do ActiveRecord::Schema.define(version: 20181201000200) do
create_table "article_categories", force: :cascade do |t| create_table "article_categories", force: :cascade do |t|
t.string "name", limit: 255, default: "", null: false 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.datetime "created_on", null: false
t.integer "financial_link_id" t.integer "financial_link_id"
t.integer "financial_transaction_type_id", null: false t.integer "financial_transaction_type_id", null: false
t.integer "reverts_id"
end end
add_index "financial_transactions", ["ordergroup_id"], name: "index_financial_transactions_on_ordergroup_id", using: :btree 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| create_table "group_order_article_quantities", force: :cascade do |t|
t.integer "group_order_article_id", limit: 4, default: 0, null: false t.integer "group_order_article_id", limit: 4, default: 0, null: false