borutus 0.2.1 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/README.md +62 -64
 - data/app/models/borutus/account.rb +97 -86
 - data/app/models/borutus/amount.rb +9 -4
 - data/app/models/borutus/amounts_extension.rb +1 -1
 - data/app/services/borutus/accounts/build_running_balance_query.rb +73 -0
 - data/db/migrate/20191025095830_add_borutus_amount_counter_cache.rb +15 -0
 - data/lib/borutus.rb +1 -0
 - data/lib/borutus/version.rb +1 -1
 - data/spec/controllers/accounts_controller_spec.rb +1 -1
 - data/spec/controllers/entries_controller_spec.rb +1 -1
 - data/spec/controllers/reports_controller_spec.rb +1 -1
 - data/spec/factories/account_factory.rb +13 -13
 - data/spec/factories/amount_factory.rb +13 -13
 - data/spec/factories/entry_factory.rb +11 -8
 - data/spec/models/account_spec.rb +98 -53
 - data/spec/models/amount_spec.rb +1 -1
 - data/spec/models/entry_spec.rb +54 -50
 - data/spec/models/tenancy_spec.rb +6 -6
 - data/spec/routing/entries_routing_spec.rb +1 -1
 - data/spec/spec_helper.rb +16 -14
 - data/spec/support/account_shared_examples.rb +3 -3
 - data/spec/support/amount_shared_examples.rb +1 -1
 - data/spec/support/factory_bot_helpers.rb +8 -0
 - metadata +44 -25
 - data/spec/support/factory_girl_helpers.rb +0 -8
 
| 
         @@ -1,13 +1,19 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            module Borutus
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
       2 
3 
     | 
    
         
             
              # The Amount class represents debit and credit amounts in the system.
         
     | 
| 
       3 
4 
     | 
    
         
             
              #
         
     | 
| 
       4 
5 
     | 
    
         
             
              # @abstract
         
     | 
| 
       5 
     | 
    
         
            -
              #   An amount must be a subclass as either a debit or a credit to be saved 
     | 
| 
      
 6 
     | 
    
         
            +
              #   An amount must be a subclass as either a debit or a credit to be saved
         
     | 
| 
      
 7 
     | 
    
         
            +
              #   to the database.
         
     | 
| 
       6 
8 
     | 
    
         
             
              #
         
     | 
| 
       7 
9 
     | 
    
         
             
              # @author Michael Bulat
         
     | 
| 
       8 
10 
     | 
    
         
             
              class Amount < ActiveRecord::Base
         
     | 
| 
       9 
     | 
    
         
            -
             
     | 
| 
       10 
     | 
    
         
            -
                belongs_to : 
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                belongs_to :entry, class_name: "Borutus::Entry"
         
     | 
| 
      
 13 
     | 
    
         
            +
                belongs_to(:account, {
         
     | 
| 
      
 14 
     | 
    
         
            +
                  class_name: "Borutus::Account",
         
     | 
| 
      
 15 
     | 
    
         
            +
                  counter_cache: :borutus_amounts_count,
         
     | 
| 
      
 16 
     | 
    
         
            +
                })
         
     | 
| 
       11 
17 
     | 
    
         | 
| 
       12 
18 
     | 
    
         
             
                validates_presence_of :type, :amount, :entry, :account
         
     | 
| 
       13 
19 
     | 
    
         
             
                # attr_accessible :account, :account_name, :amount, :entry
         
     | 
| 
         @@ -19,6 +25,5 @@ module Borutus 
     | 
|
| 
       19 
25 
     | 
    
         
             
                  self.account = Account.find_by_name!(name)
         
     | 
| 
       20 
26 
     | 
    
         
             
                end
         
     | 
| 
       21 
27 
     | 
    
         | 
| 
       22 
     | 
    
         
            -
                protected
         
     | 
| 
       23 
28 
     | 
    
         
             
              end
         
     | 
| 
       24 
29 
     | 
    
         
             
            end
         
     | 
| 
         @@ -30,7 +30,7 @@ module Borutus 
     | 
|
| 
       30 
30 
     | 
    
         
             
                #
         
     | 
| 
       31 
31 
     | 
    
         
             
                # Since this does not use the database for sumation, it may be used on non-persisted records.
         
     | 
| 
       32 
32 
     | 
    
         
             
                def balance_for_new_record
         
     | 
| 
       33 
     | 
    
         
            -
                  balance = BigDecimal 
     | 
| 
      
 33 
     | 
    
         
            +
                  balance = BigDecimal('0')
         
     | 
| 
       34 
34 
     | 
    
         
             
                  each do |amount_record|
         
     | 
| 
       35 
35 
     | 
    
         
             
                    if amount_record.amount && !amount_record.marked_for_destruction?
         
     | 
| 
       36 
36 
     | 
    
         
             
                      balance += amount_record.amount # unless amount_record.marked_for_destruction?
         
     | 
| 
         @@ -0,0 +1,73 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Borutus
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Accounts
         
     | 
| 
      
 3 
     | 
    
         
            +
                class BuildRunningBalanceQuery
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
                  STATEMENTS = {
         
     | 
| 
      
 6 
     | 
    
         
            +
                    coalesce_debit: %{ COALESCE("debit_table"."amount", 0) },
         
     | 
| 
      
 7 
     | 
    
         
            +
                    coalesce_credit: %{ COALESCE("credit_table"."amount", 0) },
         
     | 
| 
      
 8 
     | 
    
         
            +
                    amount_sum: %{ SUM("borutus_amounts".amount) AS amount },
         
     | 
| 
      
 9 
     | 
    
         
            +
                  }.freeze
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                  extend LightService::Action
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                  expects :account
         
     | 
| 
      
 14 
     | 
    
         
            +
                  promises :joins_statement, :select_statement, :group_statement
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                  executed do |c|
         
     | 
| 
      
 17 
     | 
    
         
            +
                    account = c.account
         
     | 
| 
      
 18 
     | 
    
         
            +
                    credit_amounts = account.credit_amounts
         
     | 
| 
      
 19 
     | 
    
         
            +
                    debit_amounts = account.debit_amounts
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                    credit_table = credit_amounts.joins(:entry).select(
         
     | 
| 
      
 22 
     | 
    
         
            +
                      :id,
         
     | 
| 
      
 23 
     | 
    
         
            +
                      :entry_id,
         
     | 
| 
      
 24 
     | 
    
         
            +
                      STATEMENTS[:amount_sum],
         
     | 
| 
      
 25 
     | 
    
         
            +
                    ).group(:entry_id, :id)
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                    debit_table = debit_amounts.joins(:entry).select(
         
     | 
| 
      
 28 
     | 
    
         
            +
                      :id,
         
     | 
| 
      
 29 
     | 
    
         
            +
                      :entry_id,
         
     | 
| 
      
 30 
     | 
    
         
            +
                      STATEMENTS[:amount_sum],
         
     | 
| 
      
 31 
     | 
    
         
            +
                    ).group(:entry_id, :id)
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                    sum_statement = sum_statement_from(account)
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                    c.joins_statement = joins_statement_from(credit_table, debit_table)
         
     | 
| 
      
 36 
     | 
    
         
            +
                    c.select_statement = select_statement_from(sum_statement)
         
     | 
| 
      
 37 
     | 
    
         
            +
                    c.group_statement = group_statement_from
         
     | 
| 
      
 38 
     | 
    
         
            +
                  end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                  def self.sum_statement_from(account)
         
     | 
| 
      
 41 
     | 
    
         
            +
                    if account.normal_credit_balance
         
     | 
| 
      
 42 
     | 
    
         
            +
                      %( #{STATEMENTS[:coalesce_credit]} - #{STATEMENTS[:coalesce_debit]} )
         
     | 
| 
      
 43 
     | 
    
         
            +
                    else
         
     | 
| 
      
 44 
     | 
    
         
            +
                      %( #{STATEMENTS[:coalesce_debit]} - #{STATEMENTS[:coalesce_credit]} )
         
     | 
| 
      
 45 
     | 
    
         
            +
                    end
         
     | 
| 
      
 46 
     | 
    
         
            +
                  end
         
     | 
| 
      
 47 
     | 
    
         
            +
                  private_class_method :sum_statement_from
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
                  def self.joins_statement_from(credit_table, debit_table)
         
     | 
| 
      
 50 
     | 
    
         
            +
                    %{
         
     | 
| 
      
 51 
     | 
    
         
            +
                      LEFT OUTER JOIN (#{credit_table.to_sql}) AS "credit_table" ON "credit_table".entry_id = "borutus_entries".id
         
     | 
| 
      
 52 
     | 
    
         
            +
                      LEFT OUTER JOIN (#{debit_table.to_sql}) AS "debit_table" ON "debit_table".entry_id = "borutus_entries".id
         
     | 
| 
      
 53 
     | 
    
         
            +
                    }
         
     | 
| 
      
 54 
     | 
    
         
            +
                  end
         
     | 
| 
      
 55 
     | 
    
         
            +
                  private_class_method :joins_statement_from
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
                  def self.select_statement_from(sum_statement)
         
     | 
| 
      
 58 
     | 
    
         
            +
                    %{
         
     | 
| 
      
 59 
     | 
    
         
            +
                      "borutus_entries".*,
         
     | 
| 
      
 60 
     | 
    
         
            +
                      SUM(#{sum_statement}) OVER(ORDER BY "borutus_entries"."created_at") AS balance,
         
     | 
| 
      
 61 
     | 
    
         
            +
                      #{sum_statement} AS change_amount
         
     | 
| 
      
 62 
     | 
    
         
            +
                    }
         
     | 
| 
      
 63 
     | 
    
         
            +
                  end
         
     | 
| 
      
 64 
     | 
    
         
            +
                  private_class_method :select_statement_from
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
                  def self.group_statement_from
         
     | 
| 
      
 67 
     | 
    
         
            +
                    %( "borutus_entries".id, "debit_table".amount, "credit_table".amount )
         
     | 
| 
      
 68 
     | 
    
         
            +
                  end
         
     | 
| 
      
 69 
     | 
    
         
            +
                  private_class_method :group_statement_from
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
                end
         
     | 
| 
      
 72 
     | 
    
         
            +
              end
         
     | 
| 
      
 73 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,15 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            class AddBorutusAmountCounterCache < ActiveRecord::Migration[4.2]
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
              def up
         
     | 
| 
      
 4 
     | 
    
         
            +
                add_column :borutus_accounts, :borutus_amounts_count, :integer
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
                Borutus::Account.all.pluck(:id).each do |id|
         
     | 
| 
      
 7 
     | 
    
         
            +
                  Borutus::Account.reset_counters(id, :borutus_amounts)
         
     | 
| 
      
 8 
     | 
    
         
            +
                end
         
     | 
| 
      
 9 
     | 
    
         
            +
              end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
              def down
         
     | 
| 
      
 12 
     | 
    
         
            +
                remove_column :borutus_accounts, :borutus_amounts_count
         
     | 
| 
      
 13 
     | 
    
         
            +
              end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/borutus.rb
    CHANGED
    
    
    
        data/lib/borutus/version.rb
    CHANGED
    
    
| 
         @@ -1,32 +1,32 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
             
     | 
| 
       2 
     | 
    
         
            -
              factory :account, : 
     | 
| 
      
 1 
     | 
    
         
            +
            FactoryBot.define do
         
     | 
| 
      
 2 
     | 
    
         
            +
              factory :account, class: Borutus::Account do |account|
         
     | 
| 
       3 
3 
     | 
    
         
             
                account.name
         
     | 
| 
       4 
     | 
    
         
            -
                account.contra false
         
     | 
| 
      
 4 
     | 
    
         
            +
                account.contra { false }
         
     | 
| 
       5 
5 
     | 
    
         
             
              end
         
     | 
| 
       6 
6 
     | 
    
         | 
| 
       7 
     | 
    
         
            -
              factory :asset, : 
     | 
| 
      
 7 
     | 
    
         
            +
              factory :asset, class: Borutus::Asset do |account|
         
     | 
| 
       8 
8 
     | 
    
         
             
                account.name
         
     | 
| 
       9 
     | 
    
         
            -
                account.contra false
         
     | 
| 
      
 9 
     | 
    
         
            +
                account.contra { false }
         
     | 
| 
       10 
10 
     | 
    
         
             
              end
         
     | 
| 
       11 
11 
     | 
    
         | 
| 
       12 
     | 
    
         
            -
              factory :equity, : 
     | 
| 
      
 12 
     | 
    
         
            +
              factory :equity, class: Borutus::Equity do |account|
         
     | 
| 
       13 
13 
     | 
    
         
             
                account.name
         
     | 
| 
       14 
     | 
    
         
            -
                account.contra false
         
     | 
| 
      
 14 
     | 
    
         
            +
                account.contra { false }
         
     | 
| 
       15 
15 
     | 
    
         
             
              end
         
     | 
| 
       16 
16 
     | 
    
         | 
| 
       17 
     | 
    
         
            -
              factory :expense, : 
     | 
| 
      
 17 
     | 
    
         
            +
              factory :expense, class: Borutus::Expense do |account|
         
     | 
| 
       18 
18 
     | 
    
         
             
                account.name
         
     | 
| 
       19 
     | 
    
         
            -
                account.contra false
         
     | 
| 
      
 19 
     | 
    
         
            +
                account.contra { false }
         
     | 
| 
       20 
20 
     | 
    
         
             
              end
         
     | 
| 
       21 
21 
     | 
    
         | 
| 
       22 
     | 
    
         
            -
              factory :liability, : 
     | 
| 
      
 22 
     | 
    
         
            +
              factory :liability, class: Borutus::Liability do |account|
         
     | 
| 
       23 
23 
     | 
    
         
             
                account.name
         
     | 
| 
       24 
     | 
    
         
            -
                account.contra false
         
     | 
| 
      
 24 
     | 
    
         
            +
                account.contra { false }
         
     | 
| 
       25 
25 
     | 
    
         
             
              end
         
     | 
| 
       26 
26 
     | 
    
         | 
| 
       27 
     | 
    
         
            -
              factory :revenue, : 
     | 
| 
      
 27 
     | 
    
         
            +
              factory :revenue, class: Borutus::Revenue do |account|
         
     | 
| 
       28 
28 
     | 
    
         
             
                account.name
         
     | 
| 
       29 
     | 
    
         
            -
                account.contra false
         
     | 
| 
      
 29 
     | 
    
         
            +
                account.contra { false }
         
     | 
| 
       30 
30 
     | 
    
         
             
              end
         
     | 
| 
       31 
31 
     | 
    
         | 
| 
       32 
32 
     | 
    
         
             
              sequence :name do |n|
         
     | 
| 
         @@ -1,19 +1,19 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
             
     | 
| 
       2 
     | 
    
         
            -
              factory :amount, : 
     | 
| 
       3 
     | 
    
         
            -
                amount.amount BigDecimal 
     | 
| 
       4 
     | 
    
         
            -
                amount.association :entry, : 
     | 
| 
       5 
     | 
    
         
            -
                amount.association :account, : 
     | 
| 
      
 1 
     | 
    
         
            +
            FactoryBot.define do
         
     | 
| 
      
 2 
     | 
    
         
            +
              factory :amount, class: Borutus::Amount do |amount|
         
     | 
| 
      
 3 
     | 
    
         
            +
                amount.amount { BigDecimal("473") }
         
     | 
| 
      
 4 
     | 
    
         
            +
                amount.association :entry, factory: :entry_with_credit_and_debit
         
     | 
| 
      
 5 
     | 
    
         
            +
                amount.association :account, factory: :asset
         
     | 
| 
       6 
6 
     | 
    
         
             
              end
         
     | 
| 
       7 
7 
     | 
    
         | 
| 
       8 
     | 
    
         
            -
              factory :credit_amount, : 
     | 
| 
       9 
     | 
    
         
            -
                credit_amount.amount BigDecimal 
     | 
| 
       10 
     | 
    
         
            -
                credit_amount.association :entry, : 
     | 
| 
       11 
     | 
    
         
            -
                credit_amount.association :account, : 
     | 
| 
      
 8 
     | 
    
         
            +
              factory :credit_amount, class: Borutus::CreditAmount do |credit_amount|
         
     | 
| 
      
 9 
     | 
    
         
            +
                credit_amount.amount { BigDecimal("473") }
         
     | 
| 
      
 10 
     | 
    
         
            +
                credit_amount.association :entry, factory: :entry_with_credit_and_debit
         
     | 
| 
      
 11 
     | 
    
         
            +
                credit_amount.association :account, factory: :revenue
         
     | 
| 
       12 
12 
     | 
    
         
             
              end
         
     | 
| 
       13 
13 
     | 
    
         | 
| 
       14 
     | 
    
         
            -
              factory :debit_amount, : 
     | 
| 
       15 
     | 
    
         
            -
                debit_amount.amount BigDecimal 
     | 
| 
       16 
     | 
    
         
            -
                debit_amount.association :entry, : 
     | 
| 
       17 
     | 
    
         
            -
                debit_amount.association :account, : 
     | 
| 
      
 14 
     | 
    
         
            +
              factory :debit_amount, class: Borutus::DebitAmount do |debit_amount|
         
     | 
| 
      
 15 
     | 
    
         
            +
                debit_amount.amount { BigDecimal("473") }
         
     | 
| 
      
 16 
     | 
    
         
            +
                debit_amount.association :entry, factory: :entry_with_credit_and_debit
         
     | 
| 
      
 17 
     | 
    
         
            +
                debit_amount.association :account, factory: :asset
         
     | 
| 
       18 
18 
     | 
    
         
             
              end
         
     | 
| 
       19 
19 
     | 
    
         
             
            end
         
     | 
| 
         @@ -1,11 +1,14 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
             
     | 
| 
       2 
     | 
    
         
            -
              factory :entry, : 
     | 
| 
       3 
     | 
    
         
            -
                 
     | 
| 
       4 
     | 
    
         
            -
             
     | 
| 
       5 
     | 
    
         
            -
             
     | 
| 
       6 
     | 
    
         
            -
             
     | 
| 
       7 
     | 
    
         
            -
             
     | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
      
 1 
     | 
    
         
            +
            FactoryBot.define do
         
     | 
| 
      
 2 
     | 
    
         
            +
              factory :entry, class: Borutus::Entry do
         
     | 
| 
      
 3 
     | 
    
         
            +
                description { "factory description" }
         
     | 
| 
      
 4 
     | 
    
         
            +
              end
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
              factory :entry_with_credit_and_debit, class: Borutus::Entry do
         
     | 
| 
      
 7 
     | 
    
         
            +
                description { "factory description" }
         
     | 
| 
      
 8 
     | 
    
         
            +
                
         
     | 
| 
      
 9 
     | 
    
         
            +
                after(:build) do |entry|
         
     | 
| 
      
 10 
     | 
    
         
            +
                  entry.credit_amounts << FactoryBot.build(:credit_amount, entry: entry)
         
     | 
| 
      
 11 
     | 
    
         
            +
                  entry.debit_amounts << FactoryBot.build(:debit_amount, entry: entry)
         
     | 
| 
       9 
12 
     | 
    
         
             
                end
         
     | 
| 
       10 
13 
     | 
    
         
             
              end
         
     | 
| 
       11 
14 
     | 
    
         
             
            end
         
     | 
    
        data/spec/models/account_spec.rb
    CHANGED
    
    | 
         @@ -1,39 +1,40 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            require  
     | 
| 
      
 1 
     | 
    
         
            +
            require "spec_helper"
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            module Borutus
         
     | 
| 
       4 
4 
     | 
    
         
             
              describe Account do
         
     | 
| 
       5 
     | 
    
         
            -
             
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
                let(:account) { FactoryBot.build(:account) }
         
     | 
| 
       6 
7 
     | 
    
         
             
                subject { account }
         
     | 
| 
       7 
8 
     | 
    
         | 
| 
       8 
     | 
    
         
            -
                it { is_expected.not_to be_valid } 
     | 
| 
      
 9 
     | 
    
         
            +
                it { is_expected.not_to be_valid } # must construct a child type instead
         
     | 
| 
       9 
10 
     | 
    
         | 
| 
       10 
11 
     | 
    
         
             
                describe ".types" do
         
     | 
| 
       11 
12 
     | 
    
         
             
                  it "lists the available types" do
         
     | 
| 
       12 
     | 
    
         
            -
                    expect(described_class.types) 
     | 
| 
       13 
     | 
    
         
            -
                      to match_array([Asset, Equity, Expense, Liability, Revenue])
         
     | 
| 
      
 13 
     | 
    
         
            +
                    expect(described_class.types)
         
     | 
| 
      
 14 
     | 
    
         
            +
                      .to match_array([Asset, Equity, Expense, Liability, Revenue])
         
     | 
| 
       14 
15 
     | 
    
         
             
                  end
         
     | 
| 
       15 
16 
     | 
    
         
             
                end
         
     | 
| 
       16 
17 
     | 
    
         | 
| 
       17 
18 
     | 
    
         
             
                describe ".entries.with_running_balance" do
         
     | 
| 
       18 
     | 
    
         
            -
                  let(:mock_document) {  
     | 
| 
      
 19 
     | 
    
         
            +
                  let(:mock_document) { FactoryBot.create(:asset) }
         
     | 
| 
       19 
20 
     | 
    
         
             
                  let!(:accounts_receivable) do
         
     | 
| 
       20 
     | 
    
         
            -
                     
     | 
| 
      
 21 
     | 
    
         
            +
                    FactoryBot.create(:asset, name: "Accounts Receivable")
         
     | 
| 
       21 
22 
     | 
    
         
             
                  end
         
     | 
| 
       22 
23 
     | 
    
         
             
                  let!(:sales_revenue) do
         
     | 
| 
       23 
     | 
    
         
            -
                     
     | 
| 
      
 24 
     | 
    
         
            +
                    FactoryBot.create(:revenue, name: "Sales Revenue")
         
     | 
| 
       24 
25 
     | 
    
         
             
                  end
         
     | 
| 
       25 
26 
     | 
    
         
             
                  let!(:sales_tax_payable) do
         
     | 
| 
       26 
     | 
    
         
            -
                     
     | 
| 
      
 27 
     | 
    
         
            +
                    FactoryBot.create(:liability, name: "Sales Tax Payable")
         
     | 
| 
       27 
28 
     | 
    
         
             
                  end
         
     | 
| 
       28 
29 
     | 
    
         
             
                  let!(:entry_1) do
         
     | 
| 
       29 
30 
     | 
    
         
             
                    Borutus::Entry.new({
         
     | 
| 
       30 
31 
     | 
    
         
             
                      description: "Sold some widgets",
         
     | 
| 
       31 
32 
     | 
    
         
             
                      commercial_document: mock_document,
         
     | 
| 
       32 
     | 
    
         
            -
                      debits: [{account: accounts_receivable, amount: 50}],
         
     | 
| 
      
 33 
     | 
    
         
            +
                      debits: [{ account: accounts_receivable, amount: 50 }],
         
     | 
| 
       33 
34 
     | 
    
         
             
                      credits: [
         
     | 
| 
       34 
     | 
    
         
            -
                        {account: sales_revenue, amount: 45},
         
     | 
| 
       35 
     | 
    
         
            -
                        {account: sales_tax_payable, amount: 5}
         
     | 
| 
       36 
     | 
    
         
            -
                      ]
         
     | 
| 
      
 35 
     | 
    
         
            +
                        { account: sales_revenue, amount: 45 },
         
     | 
| 
      
 36 
     | 
    
         
            +
                        { account: sales_tax_payable, amount: 5 },
         
     | 
| 
      
 37 
     | 
    
         
            +
                      ],
         
     | 
| 
       37 
38 
     | 
    
         
             
                    })
         
     | 
| 
       38 
39 
     | 
    
         
             
                  end
         
     | 
| 
       39 
40 
     | 
    
         
             
                  let!(:entry_2) do
         
     | 
| 
         @@ -41,20 +42,20 @@ module Borutus 
     | 
|
| 
       41 
42 
     | 
    
         
             
                      description: "Cancel Accounts receivable some widgets again",
         
     | 
| 
       42 
43 
     | 
    
         
             
                      commercial_document: mock_document,
         
     | 
| 
       43 
44 
     | 
    
         
             
                      debits: [
         
     | 
| 
       44 
     | 
    
         
            -
                        {account: accounts_receivable, amount: -30},
         
     | 
| 
      
 45 
     | 
    
         
            +
                        { account: accounts_receivable, amount: -30 },
         
     | 
| 
       45 
46 
     | 
    
         
             
                      ],
         
     | 
| 
       46 
47 
     | 
    
         
             
                      credits: [
         
     | 
| 
       47 
     | 
    
         
            -
                        {account: sales_revenue, amount: -25},
         
     | 
| 
       48 
     | 
    
         
            -
                        {account: sales_tax_payable, amount: -5},
         
     | 
| 
       49 
     | 
    
         
            -
                      ]
         
     | 
| 
      
 48 
     | 
    
         
            +
                        { account: sales_revenue, amount: -25 },
         
     | 
| 
      
 49 
     | 
    
         
            +
                        { account: sales_tax_payable, amount: -5 },
         
     | 
| 
      
 50 
     | 
    
         
            +
                      ],
         
     | 
| 
       50 
51 
     | 
    
         
             
                    })
         
     | 
| 
       51 
52 
     | 
    
         
             
                  end
         
     | 
| 
       52 
53 
     | 
    
         
             
                  let!(:entry_3) do
         
     | 
| 
       53 
54 
     | 
    
         
             
                    Borutus::Entry.new({
         
     | 
| 
       54 
55 
     | 
    
         
             
                      description: "Cancel Accounts receivable",
         
     | 
| 
       55 
56 
     | 
    
         
             
                      commercial_document: mock_document,
         
     | 
| 
       56 
     | 
    
         
            -
                      debits: [{account: sales_tax_payable, amount: 15}],
         
     | 
| 
       57 
     | 
    
         
            -
                      credits: [{account: accounts_receivable, amount: 15}],
         
     | 
| 
      
 57 
     | 
    
         
            +
                      debits: [{ account: sales_tax_payable, amount: 15 }],
         
     | 
| 
      
 58 
     | 
    
         
            +
                      credits: [{ account: accounts_receivable, amount: 15 }],
         
     | 
| 
       58 
59 
     | 
    
         
             
                    })
         
     | 
| 
       59 
60 
     | 
    
         
             
                  end
         
     | 
| 
       60 
61 
     | 
    
         | 
| 
         @@ -84,12 +85,56 @@ module Borutus 
     | 
|
| 
       84 
85 
     | 
    
         
             
                  end
         
     | 
| 
       85 
86 
     | 
    
         
             
                end
         
     | 
| 
       86 
87 
     | 
    
         | 
| 
      
 88 
     | 
    
         
            +
                describe ".with_amounts" do
         
     | 
| 
      
 89 
     | 
    
         
            +
                  let(:mock_document) { FactoryBot.create(:asset) }
         
     | 
| 
      
 90 
     | 
    
         
            +
                  let!(:cash) do
         
     | 
| 
      
 91 
     | 
    
         
            +
                    FactoryBot.create(:asset, name: "Cash")
         
     | 
| 
      
 92 
     | 
    
         
            +
                  end
         
     | 
| 
      
 93 
     | 
    
         
            +
                  let!(:accounts_receivable) do
         
     | 
| 
      
 94 
     | 
    
         
            +
                    FactoryBot.create(:asset, name: "Accounts Receivable")
         
     | 
| 
      
 95 
     | 
    
         
            +
                  end
         
     | 
| 
      
 96 
     | 
    
         
            +
                  let!(:sales_revenue) do
         
     | 
| 
      
 97 
     | 
    
         
            +
                    FactoryBot.create(:revenue, name: "Sales Revenue")
         
     | 
| 
      
 98 
     | 
    
         
            +
                  end
         
     | 
| 
      
 99 
     | 
    
         
            +
                  let!(:sales_tax_payable) do
         
     | 
| 
      
 100 
     | 
    
         
            +
                    FactoryBot.create(:liability, name: "Sales Tax Payable")
         
     | 
| 
      
 101 
     | 
    
         
            +
                  end
         
     | 
| 
      
 102 
     | 
    
         
            +
                  let!(:entry_1) do
         
     | 
| 
      
 103 
     | 
    
         
            +
                    Borutus::Entry.new({
         
     | 
| 
      
 104 
     | 
    
         
            +
                      description: "Sold some widgets",
         
     | 
| 
      
 105 
     | 
    
         
            +
                      commercial_document: mock_document,
         
     | 
| 
      
 106 
     | 
    
         
            +
                      debits: [{ account: accounts_receivable, amount: 50 }],
         
     | 
| 
      
 107 
     | 
    
         
            +
                      credits: [
         
     | 
| 
      
 108 
     | 
    
         
            +
                        { account: sales_revenue, amount: 45 },
         
     | 
| 
      
 109 
     | 
    
         
            +
                        { account: sales_tax_payable, amount: 5 },
         
     | 
| 
      
 110 
     | 
    
         
            +
                      ],
         
     | 
| 
      
 111 
     | 
    
         
            +
                    })
         
     | 
| 
      
 112 
     | 
    
         
            +
                  end
         
     | 
| 
      
 113 
     | 
    
         
            +
             
     | 
| 
      
 114 
     | 
    
         
            +
                  it "only returns with borutus_amounts_count > 0" do
         
     | 
| 
      
 115 
     | 
    
         
            +
                    entry_1.save
         
     | 
| 
      
 116 
     | 
    
         
            +
             
     | 
| 
      
 117 
     | 
    
         
            +
                    accounts = Borutus::Account.with_amounts
         
     | 
| 
      
 118 
     | 
    
         
            +
                    expect(accounts.count).to eq 3
         
     | 
| 
      
 119 
     | 
    
         
            +
             
     | 
| 
      
 120 
     | 
    
         
            +
                    account_names = accounts.pluck(:name)
         
     | 
| 
      
 121 
     | 
    
         
            +
             
     | 
| 
      
 122 
     | 
    
         
            +
                    [
         
     | 
| 
      
 123 
     | 
    
         
            +
                      "Accounts Receivable",
         
     | 
| 
      
 124 
     | 
    
         
            +
                      "Sales Revenue",
         
     | 
| 
      
 125 
     | 
    
         
            +
                      "Sales Tax Payable",
         
     | 
| 
      
 126 
     | 
    
         
            +
                    ].each do |account_name|
         
     | 
| 
      
 127 
     | 
    
         
            +
                      expect(account_names).to include account_name
         
     | 
| 
      
 128 
     | 
    
         
            +
                    end
         
     | 
| 
      
 129 
     | 
    
         
            +
                  end
         
     | 
| 
      
 130 
     | 
    
         
            +
                end
         
     | 
| 
      
 131 
     | 
    
         
            +
             
     | 
| 
       87 
132 
     | 
    
         
             
                describe "when using a child type" do
         
     | 
| 
       88 
     | 
    
         
            -
                  let(:account) {  
     | 
| 
      
 133 
     | 
    
         
            +
                  let(:account) { FactoryBot.create(:account, type: "Finance::Asset") }
         
     | 
| 
       89 
134 
     | 
    
         
             
                  it { is_expected.to be_valid }
         
     | 
| 
       90 
135 
     | 
    
         | 
| 
       91 
136 
     | 
    
         
             
                  it "should be unique per name" do
         
     | 
| 
       92 
     | 
    
         
            -
                    conflict =  
     | 
| 
      
 137 
     | 
    
         
            +
                    conflict = FactoryBot.build(:account, name: account.name, type: account.type)
         
     | 
| 
       93 
138 
     | 
    
         
             
                    expect(conflict).not_to be_valid
         
     | 
| 
       94 
139 
     | 
    
         
             
                    expect(conflict.errors[:name]).to eq(["has already been taken"])
         
     | 
| 
       95 
140 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -114,36 +159,36 @@ module Borutus 
     | 
|
| 
       114 
159 
     | 
    
         
             
                  context "when given correct entries" do
         
     | 
| 
       115 
160 
     | 
    
         
             
                    before {
         
     | 
| 
       116 
161 
     | 
    
         
             
                      # credit accounts
         
     | 
| 
       117 
     | 
    
         
            -
                      liability =  
     | 
| 
       118 
     | 
    
         
            -
                      equity =  
     | 
| 
       119 
     | 
    
         
            -
                      revenue =  
     | 
| 
       120 
     | 
    
         
            -
                      contra_asset =  
     | 
| 
       121 
     | 
    
         
            -
                      contra_expense =  
     | 
| 
      
 162 
     | 
    
         
            +
                      liability = FactoryBot.create(:liability)
         
     | 
| 
      
 163 
     | 
    
         
            +
                      equity = FactoryBot.create(:equity)
         
     | 
| 
      
 164 
     | 
    
         
            +
                      revenue = FactoryBot.create(:revenue)
         
     | 
| 
      
 165 
     | 
    
         
            +
                      contra_asset = FactoryBot.create(:asset, contra: true)
         
     | 
| 
      
 166 
     | 
    
         
            +
                      contra_expense = FactoryBot.create(:expense, contra: true)
         
     | 
| 
       122 
167 
     | 
    
         
             
                      # credit amounts
         
     | 
| 
       123 
     | 
    
         
            -
                      ca1 =  
     | 
| 
       124 
     | 
    
         
            -
                      ca2 =  
     | 
| 
       125 
     | 
    
         
            -
                      ca3 =  
     | 
| 
       126 
     | 
    
         
            -
                      ca4 =  
     | 
| 
       127 
     | 
    
         
            -
                      ca5 =  
     | 
| 
      
 168 
     | 
    
         
            +
                      ca1 = FactoryBot.build(:credit_amount, account: liability, amount: 100_000)
         
     | 
| 
      
 169 
     | 
    
         
            +
                      ca2 = FactoryBot.build(:credit_amount, account: equity, amount: 1000)
         
     | 
| 
      
 170 
     | 
    
         
            +
                      ca3 = FactoryBot.build(:credit_amount, account: revenue, amount: 40_404)
         
     | 
| 
      
 171 
     | 
    
         
            +
                      ca4 = FactoryBot.build(:credit_amount, account: contra_asset, amount: 2)
         
     | 
| 
      
 172 
     | 
    
         
            +
                      ca5 = FactoryBot.build(:credit_amount, account: contra_expense, amount: 333)
         
     | 
| 
       128 
173 
     | 
    
         | 
| 
       129 
174 
     | 
    
         
             
                      # debit accounts
         
     | 
| 
       130 
     | 
    
         
            -
                      asset =  
     | 
| 
       131 
     | 
    
         
            -
                      expense =  
     | 
| 
       132 
     | 
    
         
            -
                      contra_liability =  
     | 
| 
       133 
     | 
    
         
            -
                      contra_equity =  
     | 
| 
       134 
     | 
    
         
            -
                      contra_revenue =  
     | 
| 
      
 175 
     | 
    
         
            +
                      asset = FactoryBot.create(:asset)
         
     | 
| 
      
 176 
     | 
    
         
            +
                      expense = FactoryBot.create(:expense)
         
     | 
| 
      
 177 
     | 
    
         
            +
                      contra_liability = FactoryBot.create(:liability, contra: true)
         
     | 
| 
      
 178 
     | 
    
         
            +
                      contra_equity = FactoryBot.create(:equity, contra: true)
         
     | 
| 
      
 179 
     | 
    
         
            +
                      contra_revenue = FactoryBot.create(:revenue, contra: true)
         
     | 
| 
       135 
180 
     | 
    
         
             
                      # debit amounts
         
     | 
| 
       136 
     | 
    
         
            -
                      da1 =  
     | 
| 
       137 
     | 
    
         
            -
                      da2 =  
     | 
| 
       138 
     | 
    
         
            -
                      da3 =  
     | 
| 
       139 
     | 
    
         
            -
                      da4 =  
     | 
| 
       140 
     | 
    
         
            -
                      da5 =  
     | 
| 
       141 
     | 
    
         
            -
             
     | 
| 
       142 
     | 
    
         
            -
                       
     | 
| 
       143 
     | 
    
         
            -
                       
     | 
| 
       144 
     | 
    
         
            -
                       
     | 
| 
       145 
     | 
    
         
            -
                       
     | 
| 
       146 
     | 
    
         
            -
                       
     | 
| 
      
 181 
     | 
    
         
            +
                      da1 = FactoryBot.build(:debit_amount, account: asset, amount: 100_000)
         
     | 
| 
      
 182 
     | 
    
         
            +
                      da2 = FactoryBot.build(:debit_amount, account: expense, amount: 1000)
         
     | 
| 
      
 183 
     | 
    
         
            +
                      da3 = FactoryBot.build(:debit_amount, account: contra_liability, amount: 40_404)
         
     | 
| 
      
 184 
     | 
    
         
            +
                      da4 = FactoryBot.build(:debit_amount, account: contra_equity, amount: 2)
         
     | 
| 
      
 185 
     | 
    
         
            +
                      da5 = FactoryBot.build(:debit_amount, account: contra_revenue, amount: 333)
         
     | 
| 
      
 186 
     | 
    
         
            +
             
     | 
| 
      
 187 
     | 
    
         
            +
                      FactoryBot.create(:entry, credit_amounts: [ca1], debit_amounts: [da1])
         
     | 
| 
      
 188 
     | 
    
         
            +
                      FactoryBot.create(:entry, credit_amounts: [ca2], debit_amounts: [da2])
         
     | 
| 
      
 189 
     | 
    
         
            +
                      FactoryBot.create(:entry, credit_amounts: [ca3], debit_amounts: [da3])
         
     | 
| 
      
 190 
     | 
    
         
            +
                      FactoryBot.create(:entry, credit_amounts: [ca4], debit_amounts: [da4])
         
     | 
| 
      
 191 
     | 
    
         
            +
                      FactoryBot.create(:entry, credit_amounts: [ca5], debit_amounts: [da5])
         
     | 
| 
       147 
192 
     | 
    
         
             
                    }
         
     | 
| 
       148 
193 
     | 
    
         | 
| 
       149 
194 
     | 
    
         
             
                    it { is_expected.to eq(0) }
         
     | 
| 
         @@ -152,9 +197,9 @@ module Borutus 
     | 
|
| 
       152 
197 
     | 
    
         | 
| 
       153 
198 
     | 
    
         
             
                describe "#amounts" do
         
     | 
| 
       154 
199 
     | 
    
         
             
                  it "returns all credit and debit amounts" do
         
     | 
| 
       155 
     | 
    
         
            -
                    equity =  
     | 
| 
       156 
     | 
    
         
            -
                    asset =  
     | 
| 
       157 
     | 
    
         
            -
                    expense =  
     | 
| 
      
 200 
     | 
    
         
            +
                    equity = FactoryBot.create(:equity)
         
     | 
| 
      
 201 
     | 
    
         
            +
                    asset = FactoryBot.create(:asset)
         
     | 
| 
      
 202 
     | 
    
         
            +
                    expense = FactoryBot.create(:expense)
         
     | 
| 
       158 
203 
     | 
    
         | 
| 
       159 
204 
     | 
    
         
             
                    investment = Entry.new(
         
     | 
| 
       160 
205 
     | 
    
         
             
                      description: "Initial investment",
         
     | 
| 
         @@ -180,9 +225,9 @@ module Borutus 
     | 
|
| 
       180 
225 
     | 
    
         | 
| 
       181 
226 
     | 
    
         
             
                describe "#entries" do
         
     | 
| 
       182 
227 
     | 
    
         
             
                  it "returns all credit and debit entries" do
         
     | 
| 
       183 
     | 
    
         
            -
                    equity =  
     | 
| 
       184 
     | 
    
         
            -
                    asset =  
     | 
| 
       185 
     | 
    
         
            -
                    expense =  
     | 
| 
      
 228 
     | 
    
         
            +
                    equity = FactoryBot.create(:equity)
         
     | 
| 
      
 229 
     | 
    
         
            +
                    asset = FactoryBot.create(:asset)
         
     | 
| 
      
 230 
     | 
    
         
            +
                    expense = FactoryBot.create(:expense)
         
     | 
| 
       186 
231 
     | 
    
         | 
| 
       187 
232 
     | 
    
         
             
                    investment = Entry.new(
         
     | 
| 
       188 
233 
     | 
    
         
             
                      description: "Initial investment",
         
     |