Allow deletion of financial transactions
This commit is contained in:
parent
260ef90f6b
commit
ff76fa60c0
14 changed files with 79 additions and 8 deletions
|
@ -537,3 +537,7 @@ span.positive_amount {
|
||||||
span.negative_amout {
|
span.negative_amout {
|
||||||
color: red;
|
color: red;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.deleted_row {
|
||||||
|
text-decoration: line-through;
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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'
|
||||||
|
|
||||||
|
|
||||||
|
%label{for: 'show_hidden'}
|
||||||
|
= check_box_tag 'show_hidden', 1, params[:show_hidden]
|
||||||
|
= t '.show_hidden'
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
$('#transactions').html('<%= escape_javascript(render("transactions", with_csv: true)) %>');
|
$('#transactions').html('<%= escape_javascript(render("transactions", with_csv: true, with_hidden: true)) %>');
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue