diff --git a/app/models/financial_transaction_class.rb b/app/models/financial_transaction_class.rb index 39ba2cdb..43ded5fd 100644 --- a/app/models/financial_transaction_class.rb +++ b/app/models/financial_transaction_class.rb @@ -1,10 +1,14 @@ class FinancialTransactionClass < ApplicationRecord has_many :financial_transaction_types, dependent: :destroy has_many :supplier_category, dependent: :restrict_with_exception + has_many :financial_transactions, through: :financial_transaction_types + has_many :ordergroups, -> { distinct }, through: :financial_transactions validates :name, presence: true validates_uniqueness_of :name + after_save :update_balance_of_ordergroups + scope :sorted, -> { order(name: :asc) } def self.has_multiple_classes @@ -18,4 +22,10 @@ class FinancialTransactionClass < ApplicationRecord I18n.t('activerecord.attributes.financial_transaction.amount') end end + + private + + def update_balance_of_ordergroups + ordergroups.each { |og| og.update_balance! } + end end diff --git a/app/models/financial_transaction_type.rb b/app/models/financial_transaction_type.rb index 62ccf3ba..392a1a95 100644 --- a/app/models/financial_transaction_type.rb +++ b/app/models/financial_transaction_type.rb @@ -2,6 +2,7 @@ class FinancialTransactionType < ApplicationRecord belongs_to :financial_transaction_class belongs_to :bank_account, optional: true has_many :financial_transactions, dependent: :restrict_with_exception + has_many :ordergroups, -> { distinct }, through: :financial_transactions validates :name, presence: true validates_uniqueness_of :name @@ -9,6 +10,7 @@ class FinancialTransactionType < ApplicationRecord validates_format_of :name_short, :with => /\A[A-Za-z]*\z/ validates :financial_transaction_class, presence: true + after_save :update_balance_of_ordergroups before_destroy :restrict_deleting_last_financial_transaction_type scope :with_name_short, -> { where.not(name_short: [nil, '']) } @@ -27,4 +29,10 @@ class FinancialTransactionType < ApplicationRecord def restrict_deleting_last_financial_transaction_type raise I18n.t('model.financial_transaction_type.no_delete_last') if FinancialTransactionType.count == 1 end + + private + + def update_balance_of_ordergroups + ordergroups.each { |og| og.update_balance! } + end end diff --git a/app/models/ordergroup.rb b/app/models/ordergroup.rb index 3adcf812..2a62caf5 100644 --- a/app/models/ordergroup.rb +++ b/app/models/ordergroup.rb @@ -103,7 +103,11 @@ class Ordergroup < Group end def update_balance! - update_attribute :account_balance, financial_transactions.sum('amount') + new_account_balance = financial_transactions + .joins(financial_transaction_type: [:financial_transaction_class]) + .where({ financial_transaction_classes: { ignore_for_account_balance: false} }) + .sum(:amount) + update_attribute :account_balance, new_account_balance end def avg_jobs_per_euro diff --git a/app/views/admin/financial_transaction_classes/_form.html.haml b/app/views/admin/financial_transaction_classes/_form.html.haml index d99e34d3..65e337ff 100644 --- a/app/views/admin/financial_transaction_classes/_form.html.haml +++ b/app/views/admin/financial_transaction_classes/_form.html.haml @@ -4,6 +4,7 @@ %h3= @financial_transaction_class.new_record? ? t('.title_new') : t('.title_edit') .modal-body = f.input :name + = f.input :ignore_for_account_balance .modal-footer = link_to t('ui.close'), '#', class: 'btn', data: {dismiss: 'modal'} = f.submit class: 'btn btn-primary' diff --git a/db/schema.rb b/db/schema.rb index 3e0a9262..6e85c5d6 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -101,6 +101,7 @@ ActiveRecord::Schema.define(version: 2021_02_05_090257) do create_table "financial_transaction_classes", id: :integer, force: :cascade do |t| t.string "name", null: false + t.boolean "ignore_for_account_balance", default: false, null: false end create_table "financial_transaction_types", id: :integer, force: :cascade do |t| diff --git a/spec/models/ordergroup_spec.rb b/spec/models/ordergroup_spec.rb index 7f042417..07ab3d94 100644 --- a/spec/models/ordergroup_spec.rb +++ b/spec/models/ordergroup_spec.rb @@ -8,23 +8,51 @@ describe Ordergroup do let(:ftt3) { create :financial_transaction_type, financial_transaction_class: ftc2 } let(:user) { create :user, groups:[create(:ordergroup)] } - it 'has correct FinancialTransactionClass sums' do - og = user.ordergroup - og.add_financial_transaction!(-1, '-1', user, ftt1) - og.add_financial_transaction!(2, '2', user, ftt1) - og.add_financial_transaction!(3, '3', user, ftt1) + context 'with financial transactions' do + before do + og = user.ordergroup + og.add_financial_transaction!(-1, '-1', user, ftt1) + og.add_financial_transaction!(2, '2', user, ftt1) + og.add_financial_transaction!(3, '3', user, ftt1) - og.add_financial_transaction!(-10, '-10', user, ftt2) - og.add_financial_transaction!(20, '20', user, ftt2) - og.add_financial_transaction!(30, '30', user, ftt2) + og.add_financial_transaction!(-10, '-10', user, ftt2) + og.add_financial_transaction!(20, '20', user, ftt2) + og.add_financial_transaction!(30, '30', user, ftt2) - og.add_financial_transaction!(-100, '-100', user, ftt3) - og.add_financial_transaction!(200, '200', user, ftt3) - og.add_financial_transaction!(300, '300', user, ftt3) + og.add_financial_transaction!(-100, '-100', user, ftt3) + og.add_financial_transaction!(200, '200', user, ftt3) + og.add_financial_transaction!(300, '300', user, ftt3) + end - result = Ordergroup.include_transaction_class_sum.where(id: og).first - expect(result["sum_of_class_#{ftc1.id}"]).to eq 4 - expect(result["sum_of_class_#{ftc2.id}"]).to eq 440 + it 'has correct account balance' do + og = user.ordergroup + expect(og.account_balance).to eq 444 + + ftc1.reload + ftc1.update_attributes!(ignore_for_account_balance: true) + + og.reload + expect(og.account_balance).to eq 440 + + ftt2.reload + ftt2.update_attributes!(financial_transaction_class: ftc1) + + og.reload + expect(og.account_balance).to eq 400 + end + + it 'has correct FinancialTransactionClass sums' do + og = user.ordergroup + result = Ordergroup.include_transaction_class_sum.where(id: og).first + expect(result["sum_of_class_#{ftc1.id}"]).to eq 4 + expect(result["sum_of_class_#{ftc2.id}"]).to eq 440 + + ftt2.reload + ftt2.update_attributes!(financial_transaction_class: ftc1) + + result = Ordergroup.include_transaction_class_sum.where(id: og).first + expect(result["sum_of_class_#{ftc1.id}"]).to eq 44 + expect(result["sum_of_class_#{ftc2.id}"]).to eq 400 + end end - end