diff --git a/app/models/account_activity.rb b/app/models/account_activity.rb index 9392d1aef..d236f1f5d 100644 --- a/app/models/account_activity.rb +++ b/app/models/account_activity.rb @@ -1,4 +1,12 @@ class AccountActivity < ActiveRecord::Base belongs_to :account + belongs_to :bank_transaction + belongs_to :invoice + + after_create :update_balance + def update_balance + account.balance += sum + account.save + end end diff --git a/app/models/bank_statement.rb b/app/models/bank_statement.rb index 547d3fefc..c61089b95 100644 --- a/app/models/bank_statement.rb +++ b/app/models/bank_statement.rb @@ -3,6 +3,8 @@ class BankStatement < ActiveRecord::Base attr_accessor :th6_file + validates :bank_code, :iban, :queried_at, presence: true + def import import_th6_file && save end @@ -47,4 +49,8 @@ class BankStatement < ActiveRecord::Base self.queried_at = DateTime.strptime(row[30, 10].strip, '%y%m%d%H%M') nil end + + def bind_with_invoices + bank_transactions.unbinded.each(&:bind_with_invoice) + end end diff --git a/app/models/bank_transaction.rb b/app/models/bank_transaction.rb index 5d2b8bd7d..059504ce0 100644 --- a/app/models/bank_transaction.rb +++ b/app/models/bank_transaction.rb @@ -1,3 +1,38 @@ class BankTransaction < ActiveRecord::Base belongs_to :bank_statement + has_one :account_activity + + scope :unbinded, -> { where('id NOT IN (SELECT bank_transaction_id FROM account_activities)') } + + def binded? + account_activity.present? + end + + # For successful binding, reference number, invoice id and sum must match with the invoice + # rubocop: disable Metrics/PerceivedComplexity + # rubocop: disable Metrics/CyclomaticComplexity + def bind_with_invoice + return if binded? + registrar = Registrar.find_by(reference_no: reference_no) + return unless registrar + + match = description.match(/^[^\d]*(\d+)/) + return unless match + + invoice_id = match[1].to_i + return unless invoice_id + + invoice = registrar.invoices.find_by(id: invoice_id) + return unless invoice + + return if invoice.sum != sum + create_account_activity( + account: registrar.cash_account, + invoice: invoice, + sum: sum, + currency: currency + ) + end + # rubocop: enable Metrics/PerceivedComplexity + # rubocop: enable Metrics/CyclomaticComplexity end diff --git a/app/models/invoice.rb b/app/models/invoice.rb index fc4a1a6af..c3deacab9 100644 --- a/app/models/invoice.rb +++ b/app/models/invoice.rb @@ -27,15 +27,15 @@ class Invoice < ActiveRecord::Base invoice_items end - def total_without_vat - items.map(&:item_total_without_vat).sum + def sum_without_vat + items.map(&:item_sum_without_vat).sum end - def total_vat - total_without_vat * vat_prc + def vat + sum_without_vat * vat_prc end - def total - total_without_vat + total_vat + def sum + sum_without_vat + vat end end diff --git a/app/models/invoice_item.rb b/app/models/invoice_item.rb index 0c7e6faf8..0d3489714 100644 --- a/app/models/invoice_item.rb +++ b/app/models/invoice_item.rb @@ -1,7 +1,7 @@ class InvoiceItem < ActiveRecord::Base belongs_to :invoice - def item_total_without_vat + def item_sum_without_vat amount * price end end diff --git a/app/models/registrar.rb b/app/models/registrar.rb index e2e9a5dda..24a827d0d 100644 --- a/app/models/registrar.rb +++ b/app/models/registrar.rb @@ -5,11 +5,13 @@ class Registrar < ActiveRecord::Base has_many :contacts, dependent: :restrict_with_error has_many :api_users, dependent: :restrict_with_error has_many :messages - belongs_to :country_deprecated, foreign_key: :country_id has_many :invoices, foreign_key: 'buyer_id' + has_many :accounts + + belongs_to :country_deprecated, foreign_key: :country_id validates :name, :reg_no, :country_code, :email, presence: true - validates :name, :reg_no, uniqueness: true + validates :name, :reg_no, :reference_no, uniqueness: true validate :set_code, if: :new_record? before_create :generate_iso_11649_reference_no @@ -99,6 +101,10 @@ class Registrar < ActiveRecord::Base ) end + def cash_account + accounts.find_by(account_type: Account::CASH) + end + def domain_transfers at = DomainTransfer.arel_table DomainTransfer.where( diff --git a/app/views/admin/bank_statements/show.haml b/app/views/admin/bank_statements/show.haml index 3ce25a09d..1b352dcec 100644 --- a/app/views/admin/bank_statements/show.haml +++ b/app/views/admin/bank_statements/show.haml @@ -41,10 +41,12 @@ = sort_link(@q, 'paid_at') %th{class: 'col-xs-3'} = sort_link(@q, 'buyer_name') - %th{class: 'col-xs-3'} + %th{class: 'col-xs-2'} = sort_link(@q, 'sum') - %th{class: 'col-xs-3'} + %th{class: 'col-xs-2'} = sort_link(@q, 'currency') + %th{class: 'col-xs-2'} + = sort_link(@q, 'account_activity', t('status')) %tbody - @bank_transactions.each do |x| %tr @@ -52,6 +54,10 @@ %td= x.buyer_name %td= x.sum %td= x.currency + %td + - c = x.binded? ? 'label-success' : 'label-danger' + %span.label{class: c}= x.binded? ? t('binded') : t('not_binded') +   .row .col-md-12 = paginate @bank_transactions diff --git a/app/views/registrar/invoices/index.haml b/app/views/registrar/invoices/index.haml index 94ac37011..a544365ca 100644 --- a/app/views/registrar/invoices/index.haml +++ b/app/views/registrar/invoices/index.haml @@ -28,4 +28,4 @@ - else %td{class: 'text-danger'}= t('unpaid') %td= l(x.due_date) - %td= x.total + %td= x.sum diff --git a/app/views/registrar/invoices/partials/_items.haml b/app/views/registrar/invoices/partials/_items.haml index a3c5613b4..4babfaddd 100644 --- a/app/views/registrar/invoices/partials/_items.haml +++ b/app/views/registrar/invoices/partials/_items.haml @@ -16,17 +16,17 @@ %td= x.unit %td= x.amount %td= x.price - %td= x.item_total_without_vat + %td= x.item_sum_without_vat %tfoot %tr %th{colspan: 3} %th= t('total_without_vat') - %td= @invoice.total_without_vat + %td= @invoice.sum_without_vat %tr %th.no-border{colspan: 3} %th= t('vat', vat_prc: (@invoice.vat_prc * 100).round) - %td= @invoice.total_vat + %td= @invoice.vat %tr %th.no-border{colspan: 3} %th= t('total') - %td= @invoice.total + %td= @invoice.sum diff --git a/config/locales/en.yml b/config/locales/en.yml index 68e2991e1..141a67d64 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -694,3 +694,5 @@ en: import_file: 'Import file' bind_with_invoices: 'Bind with invoices' url: 'URL' + binded: 'Binded' + not_binded: 'Not binded' diff --git a/db/migrate/20150414124630_fix_account_activities_name.rb b/db/migrate/20150414124630_fix_account_activities_name.rb new file mode 100644 index 000000000..ea759aff9 --- /dev/null +++ b/db/migrate/20150414124630_fix_account_activities_name.rb @@ -0,0 +1,5 @@ +class FixAccountActivitiesName < ActiveRecord::Migration + def change + rename_table :account_activites, :account_activities + end +end diff --git a/db/schema.rb b/db/schema.rb index eb4e3b731..ac3748deb 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,12 +11,12 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20150414092249) do +ActiveRecord::Schema.define(version: 20150414124630) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" - create_table "account_activites", force: :cascade do |t| + create_table "account_activities", force: :cascade do |t| t.integer "account_id" t.integer "invoice_id" t.decimal "sum" diff --git a/spec/fabricators/account_fabricator.rb b/spec/fabricators/account_fabricator.rb new file mode 100644 index 000000000..8d93ccbd5 --- /dev/null +++ b/spec/fabricators/account_fabricator.rb @@ -0,0 +1,4 @@ +Fabricator(:account) do + account_type { Account::CASH } + balance 0.0 +end diff --git a/spec/fabricators/bank_statement_fabricator.rb b/spec/fabricators/bank_statement_fabricator.rb new file mode 100644 index 000000000..4219ab869 --- /dev/null +++ b/spec/fabricators/bank_statement_fabricator.rb @@ -0,0 +1,6 @@ +Fabricator(:bank_statement) do + bank_code { '767' } + iban { 'EE557700771000598731' } + queried_at { Time.zone.now } + bank_transactions(count: 2) +end diff --git a/spec/fabricators/bank_transaction_fabricator.rb b/spec/fabricators/bank_transaction_fabricator.rb new file mode 100644 index 000000000..e284bbd83 --- /dev/null +++ b/spec/fabricators/bank_transaction_fabricator.rb @@ -0,0 +1,6 @@ +Fabricator(:bank_transaction) do + currency { 'EUR' } + sum { 100.0 } + description { 'Invoice no. 1' } + reference_no { 'RF2405752128' } +end diff --git a/spec/fabricators/registrar_fabricator.rb b/spec/fabricators/registrar_fabricator.rb index ae0bad96e..a71d5fe71 100644 --- a/spec/fabricators/registrar_fabricator.rb +++ b/spec/fabricators/registrar_fabricator.rb @@ -7,6 +7,8 @@ Fabricator(:registrar) do zip 'Postal' email 'info@registrar1.ee' country_code 'EE' + reference_no { sequence(:reference_no) { |i| "RF#{i}" } } + accounts(count: 1) end Fabricator(:registrar1, from: :registrar) do @@ -28,3 +30,17 @@ Fabricator(:registrar2, from: :registrar) do zip 'Postal' email 'info@registrar2.ee' end + +Fabricator(:eis, from: :registrar) do + name 'EIS' + reg_no '90010019' + phone '+372 727 1000' + country_code 'EE' + vat_no 'EE101286464' + email 'info@internet.ee' + state 'Harjumaa' + city 'Tallinn' + street 'Paldiski mnt 80' + zip '10617' + url 'www.internet.ee' +end diff --git a/spec/models/bank_statement_spec.rb b/spec/models/bank_statement_spec.rb new file mode 100644 index 000000000..479096183 --- /dev/null +++ b/spec/models/bank_statement_spec.rb @@ -0,0 +1,81 @@ +require 'rails_helper' + +describe BankStatement do + it { should have_many(:bank_transactions) } + + context 'with invalid attribute' do + before :all do + @bank_statement = BankStatement.new + end + + it 'should not be valid' do + @bank_statement.valid? + @bank_statement.errors.full_messages.should match_array([ + "Bank code is missing", + "Iban is missing", + "Queried at is missing" + ]) + end + + # it 'should not have any versions' do + # @bank_statement.versions.should == [] + # end + end + + context 'with valid attributes' do + before :all do + @bank_statement = Fabricate(:bank_statement) + end + + it 'should be valid' do + @bank_statement.valid? + @bank_statement.errors.full_messages.should match_array([]) + end + + it 'should be valid twice' do + @bank_statement = Fabricate(:bank_statement) + @bank_statement.valid? + @bank_statement.errors.full_messages.should match_array([]) + end + + it 'should bind transactions with invoices' do + Fabricate(:eis) + r = Fabricate(:registrar, reference_no: 'RF7086666663') + r.issue_prepayment_invoice(200, 'add some money') + + bs = Fabricate(:bank_statement, bank_transactions: [ + Fabricate(:bank_transaction, { + sum: 240.0, # with vat + reference_no: 'RF7086666663', + description: 'Invoice no. 1' + }), + Fabricate(:bank_transaction, { + sum: 120.0, + reference_no: 'RF7086666663', + description: 'Invoice no. 1' + }) + ]) + + bs.bank_transactions.count.should == 2 + + AccountActivity.count.should == 0 + bs.bind_with_invoices + + AccountActivity.count.should == 1 + + r.cash_account.balance.should == 240.0 + + bs.bank_transactions.unbinded.count.should == 1 + end + + # it 'should have one version' do + # with_versioning do + # @bank_statement.versions.should == [] + # @bank_statement.body = 'New body' + # @bank_statement.save + # @bank_statement.errors.full_messages.should match_array([]) + # @bank_statement.versions.size.should == 1 + # end + # end + end +end diff --git a/spec/models/invoice_spec.rb b/spec/models/invoice_spec.rb index 098296a68..fda868a36 100644 --- a/spec/models/invoice_spec.rb +++ b/spec/models/invoice_spec.rb @@ -56,18 +56,18 @@ describe Invoice do @invoice.seller_address.should == 'Paldiski mnt. 123, Tallinn' end - it 'should calculate totals correctly' do + it 'should calculate sums correctly' do @invoice = Fabricate(:invoice) @invoice.vat_prc.should == BigDecimal.new('0.2') - @invoice.total_without_vat.should == BigDecimal.new('300.0') - @invoice.total_vat.should == BigDecimal.new('60.0') - @invoice.total.should == BigDecimal.new('360.0') + @invoice.sum_without_vat.should == BigDecimal.new('300.0') + @invoice.vat.should == BigDecimal.new('60.0') + @invoice.sum.should == BigDecimal.new('360.0') ii = @invoice.items.first - ii.item_total_without_vat.should == BigDecimal.new('150.0') + ii.item_sum_without_vat.should == BigDecimal.new('150.0') ii = @invoice.items.last - ii.item_total_without_vat.should == BigDecimal.new('150.0') + ii.item_sum_without_vat.should == BigDecimal.new('150.0') end # it 'should have one version' do diff --git a/spec/models/registrar_spec.rb b/spec/models/registrar_spec.rb index e4f39026b..288ff24b6 100644 --- a/spec/models/registrar_spec.rb +++ b/spec/models/registrar_spec.rb @@ -90,7 +90,7 @@ describe Registrar do @registrar.issue_prepayment_invoice(200, 'add some money') @registrar.invoices.count.should == 1 i = @registrar.invoices.first - i.total.should == BigDecimal.new('240.0') + i.sum.should == BigDecimal.new('240.0') i.description.should == 'add some money' end end