From 851e5368eb49ad8859857efe18f47bc8c4f16eda Mon Sep 17 00:00:00 2001 From: Martin Lensment Date: Wed, 15 Apr 2015 11:32:51 +0300 Subject: [PATCH] Binding interface for bank statements --- .../admin/bank_statements_controller.rb | 15 +++++++-- app/models/bank_statement.rb | 31 +++++++++++++++++-- app/models/bank_transaction.rb | 7 ++++- app/models/invoice.rb | 4 +++ app/views/admin/bank_statements/index.haml | 13 ++++++-- app/views/admin/bank_statements/show.haml | 18 ++++++----- app/views/admin/bank_transactions/show.haml | 8 +++++ app/views/layouts/application.haml | 5 +-- app/views/registrar/shared/_flash.haml | 5 +-- config/locales/en.yml | 10 ++++-- config/routes.rb | 1 + ...5075408_fix_account_balances_to_decimal.rb | 10 ++++++ db/schema.rb | 4 +-- lib/tasks/import.rake | 6 ++++ spec/models/bank_statement_spec.rb | 2 +- 15 files changed, 113 insertions(+), 26 deletions(-) create mode 100644 db/migrate/20150415075408_fix_account_balances_to_decimal.rb diff --git a/app/controllers/admin/bank_statements_controller.rb b/app/controllers/admin/bank_statements_controller.rb index ed68ef902..b667d0fb6 100644 --- a/app/controllers/admin/bank_statements_controller.rb +++ b/app/controllers/admin/bank_statements_controller.rb @@ -1,7 +1,7 @@ class Admin::BankStatementsController < AdminController load_and_authorize_resource - before_action :set_bank_statement, only: [:show, :download_import_file] + before_action :set_bank_statement, only: [:show, :download_import_file, :bind_invoices] def index @q = BankStatement.search(params[:q]) @@ -10,7 +10,8 @@ class Admin::BankStatementsController < AdminController end def show - @q = @bank_statement.bank_transactions.search(params[:q]) + @q = @bank_statement.bank_transactions.includes(:account_activity).search(params[:q]) + @q.sorts = 'account_activity_id desc' if @q.sorts.empty? @bank_transactions = @q.result.page(params[:page]) end @@ -30,6 +31,16 @@ class Admin::BankStatementsController < AdminController end end + def bind_invoices + @bank_statement.bind_invoices + + flash[:notice] = t('invoices_were_fully_binded') if @bank_statement.fully_binded? + flash[:warning] = t('invoices_were_partially_binded') if @bank_statement.partially_binded? + flash[:alert] = t('no_invoices_were_binded') if @bank_statement.not_binded? + + redirect_to [:admin, @bank_statement] + end + def download_import_file filename = @bank_statement.import_file_path.split('/').last send_data File.open(@bank_statement.import_file_path, 'r').read, filename: filename diff --git a/app/models/bank_statement.rb b/app/models/bank_statement.rb index c61089b95..231d61357 100644 --- a/app/models/bank_statement.rb +++ b/app/models/bank_statement.rb @@ -5,6 +5,10 @@ class BankStatement < ActiveRecord::Base validates :bank_code, :iban, :queried_at, presence: true + FULLY_BINDED = 'fully_binded' + PARTIALLY_BINDED = 'partially_binded' + NOT_BINDED = 'not_binded' + def import import_th6_file && save end @@ -50,7 +54,30 @@ class BankStatement < ActiveRecord::Base nil end - def bind_with_invoices - bank_transactions.unbinded.each(&:bind_with_invoice) + # TODO: Cache this to database so it can be used for searching + def status + if bank_transactions.unbinded.count == bank_transactions.count + NOT_BINDED + elsif bank_transactions.unbinded.count == 0 + FULLY_BINDED + else + PARTIALLY_BINDED + end + end + + def not_binded? + status == NOT_BINDED + end + + def partially_binded? + status == PARTIALLY_BINDED + end + + def fully_binded? + status == FULLY_BINDED + end + + def bind_invoices + bank_transactions.unbinded.each(&:bind_invoice) end end diff --git a/app/models/bank_transaction.rb b/app/models/bank_transaction.rb index 059504ce0..e37950a00 100644 --- a/app/models/bank_transaction.rb +++ b/app/models/bank_transaction.rb @@ -8,10 +8,15 @@ class BankTransaction < ActiveRecord::Base account_activity.present? end + def binded_invoice + return unless binded? + account_activity.invoice + 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 + def bind_invoice return if binded? registrar = Registrar.find_by(reference_no: reference_no) return unless registrar diff --git a/app/models/invoice.rb b/app/models/invoice.rb index c3deacab9..b269b786d 100644 --- a/app/models/invoice.rb +++ b/app/models/invoice.rb @@ -7,6 +7,10 @@ class Invoice < ActiveRecord::Base validates :invoice_type, :due_date, :currency, :seller_name, :seller_iban, :buyer_name, :invoice_items, :vat_prc, presence: true + def to_s + I18n.t('invoice_no', no: id) + end + def seller_address [seller_street, seller_city, seller_state, seller_zip].reject(&:blank?).compact.join(', ') end diff --git a/app/views/admin/bank_statements/index.haml b/app/views/admin/bank_statements/index.haml index 5304a0409..8be52ef2a 100644 --- a/app/views/admin/bank_statements/index.haml +++ b/app/views/admin/bank_statements/index.haml @@ -11,18 +11,25 @@ %table.table.table-hover.table-bordered.table-condensed %thead %tr - %th{class: 'col-xs-2'} + %th{class: 'col-xs-3'} = sort_link(@q, 'created_at', t('imported_at')) - %th{class: 'col-xs-2'} + %th{class: 'col-xs-3'} = sort_link(@q, 'bank_code') - %th{class: 'col-xs-2'} + %th{class: 'col-xs-3'} = sort_link(@q, 'iban', t('iban').upcase) + / TODO: Make this searchable by caching the status to the database + %th{class: 'col-xs-3'} + = t('status') %tbody - @bank_statements.each do |x| %tr %td= link_to(l(x.created_at), admin_bank_statement_path(x)) %td= x.bank_code %td= x.iban + - sc = 'text-success' if x.status == BankStatement::FULLY_BINDED + - sc = 'text-warning' if x.status == BankStatement::PARTIALLY_BINDED + - sc = 'text-danger' if x.status == BankStatement::NOT_BINDED + %td{class: sc}= t(x.status) .row .col-md-12 = paginate @bank_statements diff --git a/app/views/admin/bank_statements/show.haml b/app/views/admin/bank_statements/show.haml index 1b352dcec..e19f5b77b 100644 --- a/app/views/admin/bank_statements/show.haml +++ b/app/views/admin/bank_statements/show.haml @@ -3,7 +3,7 @@ %h2.text-center-xs= t('bank_statement') .col-sm-6 %h2.text-right.text-center-xs - = link_to(t('bind_with_invoices'), '#', class: 'btn btn-primary') + = link_to(t('bind_invoices'), bind_invoices_admin_bank_statement_path, class: 'btn btn-primary', method: :post) = link_to(t('back_to_bank_statements'), admin_bank_statements_path, class: 'btn btn-default') %hr %row @@ -16,9 +16,15 @@ %dt= t('bank_code') %dd= @bank_statement.bank_code - %dt= t('iban').upcase + %dt= t('iban') %dd= @bank_statement.iban + %dt= t('status') + - sc = 'text-success' if @bank_statement.status == BankStatement::FULLY_BINDED + - sc = 'text-warning' if @bank_statement.status == BankStatement::PARTIALLY_BINDED + - sc = 'text-danger' if @bank_statement.status == BankStatement::NOT_BINDED + %dd{class: sc}= t(@bank_statement.status) + %dt= t('queried_at') %dd= l(@bank_statement.queried_at) @@ -46,7 +52,7 @@ %th{class: 'col-xs-2'} = sort_link(@q, 'currency') %th{class: 'col-xs-2'} - = sort_link(@q, 'account_activity', t('status')) + = sort_link(@q, 'account_activity_id', t('status')) %tbody - @bank_transactions.each do |x| %tr @@ -54,10 +60,8 @@ %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') -   + - c = x.binded? ? 'text-success' : 'text-danger' + %td{class: c}= x.binded? ? t('binded') : t('not_binded') .row .col-md-12 = paginate @bank_transactions diff --git a/app/views/admin/bank_transactions/show.haml b/app/views/admin/bank_transactions/show.haml index 67a8860df..9b0206973 100644 --- a/app/views/admin/bank_transactions/show.haml +++ b/app/views/admin/bank_transactions/show.haml @@ -16,6 +16,14 @@ %dt= t('document_no') %dd= @bank_transaction.document_no + %dt= t('status') + - c = @bank_transaction.binded? ? 'text-success' : 'text-danger' + %dd{class: c}= @bank_transaction.binded? ? t('binded') : t('not_binded') + + - if @bank_transaction.binded? + %dt= t('binded_invoice') + %dd= link_to(@bank_transaction.binded_invoice, '#') + %dt= t('bank_reference') %dd= @bank_transaction.bank_reference diff --git a/app/views/layouts/application.haml b/app/views/layouts/application.haml index fafc5ef19..533f1c4fb 100644 --- a/app/views/layouts/application.haml +++ b/app/views/layouts/application.haml @@ -63,10 +63,7 @@ / /.nav-collapse .container - - display = (flash.empty?) ? 'none' : 'block' - #flash{style: "display: #{display};"} - - type = (flash[:notice]) ? 'bg-success' : 'bg-danger' - .alert{class: type}= flash[:notice] || flash[:alert] + = render 'registrar/shared/flash' = yield .footer.text-right diff --git a/app/views/registrar/shared/_flash.haml b/app/views/registrar/shared/_flash.haml index ecaf58e13..a829780b0 100644 --- a/app/views/registrar/shared/_flash.haml +++ b/app/views/registrar/shared/_flash.haml @@ -1,4 +1,5 @@ -- display = (flash[:notice] || flash[:alert]) ? 'block' : 'none' +- display = (flash[:notice] || flash[:alert] || flash[:warning]) ? 'block' : 'none' #flash{style: "display: #{display};"} - type = (flash[:notice]) ? 'bg-success' : 'bg-danger' - .alert{class: type}= flash[:notice] || flash[:alert] + - type = 'bg-warning' if flash[:warning] + .alert{class: type}= flash[:notice] || flash[:alert] || flash[:warning] diff --git a/config/locales/en.yml b/config/locales/en.yml index 8f9510335..520a80df9 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -659,7 +659,7 @@ en: issue_date: 'Issue date' due_date: 'Due date' payment_term: 'Payment term' - iban: 'Iban' + iban: 'IBAN' bank: 'Bank' swift: 'Swift' issuer: 'Issuer' @@ -692,7 +692,13 @@ en: bank_reference: 'Bank reference' document_no: 'Document no' import_file: 'Import file' - bind_with_invoices: 'Bind with invoices' + bind_invoices: 'Bind invoices' url: 'URL' binded: 'Binded' not_binded: 'Not binded' + binded_invoice: 'Binded invoice' + fully_binded: 'Fully binded' + partially_binded: 'Partially binded' + invoices_were_fully_binded: 'Invoices were fully binded' + invoices_were_partially_binded: 'Invoices were partially binded' + no_invoices_were_binded: 'No invoices were binded' diff --git a/config/routes.rb b/config/routes.rb index 2dadee581..882ee2be5 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -86,6 +86,7 @@ Rails.application.routes.draw do resources :keyrelays resources :bank_statements do + post 'bind_invoices', on: :member get 'download_import_file', on: :member end diff --git a/db/migrate/20150415075408_fix_account_balances_to_decimal.rb b/db/migrate/20150415075408_fix_account_balances_to_decimal.rb new file mode 100644 index 000000000..8dbae0490 --- /dev/null +++ b/db/migrate/20150415075408_fix_account_balances_to_decimal.rb @@ -0,0 +1,10 @@ +class FixAccountBalancesToDecimal < ActiveRecord::Migration + def change + Account.all.each do |x| + x.balance = 0.0 unless x.balance + x.save + end + + change_column :accounts, :balance, :decimal, null: false, default: 0 + end +end diff --git a/db/schema.rb b/db/schema.rb index ac3748deb..2bf412209 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20150414124630) do +ActiveRecord::Schema.define(version: 20150415075408) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -29,7 +29,7 @@ ActiveRecord::Schema.define(version: 20150414124630) do create_table "accounts", force: :cascade do |t| t.integer "registrar_id" t.string "account_type" - t.decimal "balance" + t.decimal "balance", default: 0.0, null: false t.datetime "created_at" t.datetime "updated_at" end diff --git a/lib/tasks/import.rake b/lib/tasks/import.rake index cb3270444..d9558993d 100644 --- a/lib/tasks/import.rake +++ b/lib/tasks/import.rake @@ -99,6 +99,12 @@ namespace :import do x.save(validate: false) end + Registrar.all.each do |x| + next if x.cash_account + x.accounts.create(account_type: Account::CASH) + x.save(validate: false) + end + puts "-----> Imported #{count} new registrars in #{(Time.zone.now.to_f - start).round(2)} seconds" end diff --git a/spec/models/bank_statement_spec.rb b/spec/models/bank_statement_spec.rb index 479096183..050895eec 100644 --- a/spec/models/bank_statement_spec.rb +++ b/spec/models/bank_statement_spec.rb @@ -59,7 +59,7 @@ describe BankStatement do bs.bank_transactions.count.should == 2 AccountActivity.count.should == 0 - bs.bind_with_invoices + bs.bind_invoices AccountActivity.count.should == 1