Refactor and improve invoices

- `runner 'Invoice.cancel_overdue_invoices'` in `schedule.rb` is
changed to `rake 'invoices:cancel_overdue'`.
- `invoices.payment_term` database column is removed and its value is
hardcoded in UI.
- `invoices.paid_at` is removed as unused
- `invoices.due_date` column's type is now `date`.
- `Invoice#invoice_items` renamed to `Invoice#items` and `Invoice`
interface to get a list of items is unified.
- Default date format in UI.
- Default translations are used.
- Tests improved.
- Specs converted to tests and removed along with factories.
- Database structure improved.
This commit is contained in:
Artur Beljajev 2018-10-17 12:21:04 +03:00
parent d86ec026e3
commit a97728c0f3
65 changed files with 758 additions and 341 deletions

View file

@ -0,0 +1,11 @@
require 'test_helper'
class AccountActivityTest < ActiveSupport::TestCase
setup do
@account_activity = account_activities(:one)
end
def test_fixture_is_valid
assert @account_activity.valid?
end
end

View file

@ -2,7 +2,7 @@ require 'test_helper'
class BankTransactionTest < ActiveSupport::TestCase
def test_matches_against_invoice_reference_number
invoices(:valid).update!(number: '2222', total: 10, reference_no: '1111')
invoices(:one).update!(account_activity: nil, number: '2222', total: 10, reference_no: '1111')
transaction = BankTransaction.new(description: 'invoice #2222', sum: 10, reference_no: '1111')
assert_difference 'AccountActivity.count' do
@ -20,7 +20,7 @@ class BankTransactionTest < ActiveSupport::TestCase
end
def test_underpayment_is_not_matched_with_invoice
invoices(:valid).update!(number: '2222', total: 10)
invoices(:one).update!(account_activity: nil, number: '2222', total: 10)
transaction = BankTransaction.new(sum: 9)
assert_no_difference 'AccountActivity.count' do
@ -30,7 +30,7 @@ class BankTransactionTest < ActiveSupport::TestCase
end
def test_overpayment_is_not_matched_with_invoice
invoices(:valid).update!(number: '2222', total: 10)
invoices(:one).update!(account_activity: nil, number: '2222', total: 10)
transaction = BankTransaction.new(sum: 11)
assert_no_difference 'AccountActivity.count' do
@ -40,7 +40,7 @@ class BankTransactionTest < ActiveSupport::TestCase
end
def test_cancelled_invoice_is_not_matched
invoices(:valid).update!(number: '2222', total: 10, cancelled_at: '2010-07-05')
invoices(:one).update!(account_activity: nil, number: '2222', total: 10, cancelled_at: '2010-07-05')
transaction = BankTransaction.new(sum: 10)
assert_no_difference 'AccountActivity.count' do

View file

@ -0,0 +1,69 @@
require 'test_helper'
class CancellableInvoiceTest < ActiveSupport::TestCase
setup do
@invoice = invoices(:one)
end
def test_non_cancelled_scope_returns_non_cancelled_invoices
@invoice.update!(cancelled_at: nil)
assert Invoice.non_cancelled.include?(@invoice), 'Should return cancelled invoice'
end
def test_non_cancelled_scope_does_not_return_cancelled_invoices
@invoice.update!(cancelled_at: '2010-07-05')
assert_not Invoice.non_cancelled.include?(@invoice), 'Should not return cancelled invoice'
end
def test_cancellable_when_unpaid_and_not_yet_cancelled
@invoice.account_activity = nil
@invoice.cancelled_at = nil
assert @invoice.cancellable?
end
def test_not_cancellable_when_paid
assert @invoice.paid?
assert_not @invoice.cancellable?
end
def test_not_cancellable_when_already_cancelled
@invoice.cancelled_at = '2010-07-05'
assert_not @invoice.cancellable?
end
def test_cancels_an_invoice
travel_to Time.zone.parse('2010-07-05 08:00')
@invoice.account_activity = nil
assert @invoice.cancellable?
assert_nil @invoice.cancelled_at
@invoice.cancel
@invoice.reload
assert @invoice.cancelled?
assert_equal Time.zone.parse('2010-07-05 08:00'), @invoice.cancelled_at
end
def test_throws_an_exception_when_trying_to_cancel_already_cancelled_invoice
@invoice.cancelled_at = '2010-07-05'
e = assert_raise do
@invoice.cancel
end
assert_equal 'Invoice cannot be cancelled', e.message
end
def test_not_cancelled
@invoice.cancelled_at = nil
assert @invoice.not_cancelled?
assert_not @invoice.cancelled?
end
def test_cancelled
@invoice.cancelled_at = '2010-07-05'
assert @invoice.cancelled?
assert_not @invoice.not_cancelled?
end
end

View file

@ -0,0 +1,53 @@
require 'test_helper'
class InvoiceTest < ActiveSupport::TestCase
setup do
@invoice = invoices(:one)
end
def test_unpaid_scope_returns_unpaid_invoices
@invoice.account_activity = nil
assert Invoice.unpaid.include?(@invoice), 'Should return unpaid invoice'
end
def test_unpaid_scope_does_not_return_paid_invoices
assert @invoice.paid?
assert_not Invoice.unpaid.include?(@invoice), 'Should not return paid invoice'
end
def test_paid_when_there_is_an_account_activity
assert @invoice.account_activity
assert @invoice.paid?
assert_not @invoice.unpaid?
end
def test_unpaid_when_there_is_no_account_activity
@invoice.account_activity = nil
assert @invoice.unpaid?
assert_not @invoice.paid?
end
def test_payable_when_unpaid_and_not_cancelled
@invoice.account_activity = nil
@invoice.cancelled_at = nil
assert @invoice.payable?
end
def test_not_payable_when_already_paid
assert @invoice.paid?
assert_not @invoice.payable?
end
def test_not_payable_when_cancelled
@invoice.cancelled_at = '2010-07-05'
assert_not @invoice.payable?
end
def test_returns_receipt_date
assert_equal Time.zone.parse('2010-07-05 10:00'), @invoice.account_activity.created_at
assert_equal Date.parse('2010-07-05'), @invoice.receipt_date
end
end

View file

@ -0,0 +1,8 @@
require 'test_helper'
class InvoiceItemTest < ActiveSupport::TestCase
def test_calculates_sum_without_vat
invoice_item = InvoiceItem.new(price: 5, quantity: 2)
assert_equal 10, invoice_item.item_sum_without_vat
end
end

View file

@ -2,11 +2,40 @@ require 'test_helper'
class InvoiceTest < ActiveSupport::TestCase
setup do
@invoice = invoices(:valid)
@invoice = invoices(:one)
end
def test_valid
assert @invoice.valid?
def test_fixture_is_valid
assert @invoice.valid?, proc { @invoice.errors.full_messages }
end
def test_overdue_scope_returns_unpaid_uncancelled_invoices_with_past_due_date
travel_to Time.zone.parse('2010-07-05')
@invoice.update!(account_activity: nil, cancelled_at: nil, due_date: '2010-07-04')
assert Invoice.overdue.include?(@invoice), 'Should return overdue invoice'
end
def test_overdue_scope_does_not_return_paid_invoices
assert @invoice.paid?
assert_not Invoice.overdue.include?(@invoice), 'Should not return paid invoice'
end
def test_overdue_scope_does_not_return_cancelled_invoices
@invoice.update!(cancelled_at: '2010-07-05')
assert_not Invoice.overdue.include?(@invoice), 'Should not return cancelled invoice'
end
def test_overdue_scope_does_not_return_invoices_with_due_due_of_today_or_in_the_future
travel_to Time.zone.parse('2010-07-05')
@invoice.update!(due_date: '2010-07-05')
assert_not Invoice.overdue.include?(@invoice), 'Should not return non-overdue invoice'
end
def test_invalid_without_issue_date
@invoice.issue_date = nil
assert @invoice.invalid?
end
def test_optional_vat_rate
@ -30,7 +59,7 @@ class InvoiceTest < ActiveSupport::TestCase
def test_serializes_and_deserializes_vat_rate
invoice = @invoice.dup
invoice.invoice_items = @invoice.invoice_items
invoice.items = @invoice.items
invoice.vat_rate = BigDecimal('25.5')
invoice.save!
invoice.reload
@ -42,7 +71,7 @@ class InvoiceTest < ActiveSupport::TestCase
invoice = @invoice.dup
invoice.vat_rate = nil
invoice.buyer = registrar
invoice.invoice_items = @invoice.invoice_items
invoice.items = @invoice.items
registrar.stub(:effective_vat_rate, BigDecimal(55)) do
invoice.save!
@ -59,7 +88,9 @@ class InvoiceTest < ActiveSupport::TestCase
end
def test_calculates_vat_amount
assert_equal BigDecimal('1.5'), @invoice.vat_amount
invoice_item = InvoiceItem.new(price: 25, quantity: 2)
invoice = Invoice.new(vat_rate: 10, items: [invoice_item, invoice_item.dup])
assert_equal 10, invoice.vat_amount
end
def test_vat_amount_is_zero_when_vat_rate_is_blank
@ -69,7 +100,7 @@ class InvoiceTest < ActiveSupport::TestCase
def test_calculates_subtotal
line_item = InvoiceItem.new
invoice = Invoice.new(invoice_items: [line_item, line_item])
invoice = Invoice.new(items: [line_item, line_item])
line_item.stub(:item_sum_without_vat, BigDecimal('2.5')) do
assert_equal BigDecimal(5), invoice.subtotal
@ -84,7 +115,7 @@ class InvoiceTest < ActiveSupport::TestCase
line_item = InvoiceItem.new
invoice = Invoice.new
invoice.vat_rate = 10
invoice.invoice_items = [line_item, line_item]
invoice.items = [line_item, line_item]
line_item.stub(:item_sum_without_vat, BigDecimal('2.5')) do
assert_equal BigDecimal('5.50'), invoice.total
@ -102,8 +133,25 @@ class InvoiceTest < ActiveSupport::TestCase
invoice = @invoice.dup
invoice.buyer_vat_no = nil
invoice.buyer = registrar
invoice.invoice_items = @invoice.invoice_items
invoice.items = @invoice.items
invoice.save!
assert_equal 'US1234', invoice.buyer_vat_no
end
end
def test_invalid_without_invoice_items
@invoice.items.clear
assert @invoice.invalid?
end
def test_iterates_over_invoice_items
invoice = Invoice.new(items: [InvoiceItem.new(description: 'test')])
iteration_count = 0
invoice.each do |invoice_item|
assert_equal 'test', invoice_item.description
iteration_count += 1
end
assert_equal 1, iteration_count
end
end

View file

@ -10,8 +10,8 @@ class BankLinkTest < ActiveSupport::TestCase
@invoice = invoices(:for_payments_test)
invoice_item = invoice_items(:one)
@invoice.invoice_items << invoice_item
@invoice.invoice_items << invoice_item
@invoice.items << invoice_item
@invoice.items << invoice_item
travel_to '2018-04-01 00:30 +0300'
create_new_bank_link

View file

@ -7,8 +7,8 @@ class EveryPayTest < ActiveSupport::TestCase
@invoice = invoices(:for_payments_test)
invoice_item = invoice_items(:one)
@invoice.invoice_items << invoice_item
@invoice.invoice_items << invoice_item
@invoice.items << invoice_item
@invoice.items << invoice_item
params = {
response:

View file

@ -83,4 +83,17 @@ class RegistrarTest < ActiveSupport::TestCase
registrars(:goodnames).update!(reference_no: '1234')
end
end
def test_issues_new_invoice
travel_to Time.zone.parse('2010-07-05')
@original_days_to_keep_invoices_active_setting = Setting.days_to_keep_invoices_active
Setting.days_to_keep_invoices_active = 10
invoice = @registrar.issue_prepayment_invoice(100)
assert_equal Date.parse('2010-07-05'), invoice.issue_date
assert_equal Date.parse('2010-07-15'), invoice.due_date
Setting.days_to_keep_invoices_active = @original_days_to_keep_invoices_active_setting
end
end