Invoice cancelling

This commit is contained in:
Martin Lensment 2015-04-27 11:15:09 +03:00
parent 56d7f9f2e2
commit a26ce110b2
17 changed files with 113 additions and 25 deletions

View file

@ -51,3 +51,6 @@
@media (min-width: 768px) and (max-width: 991px) @media (min-width: 768px) and (max-width: 991px)
.control-label .control-label
text-align: left !important text-align: left !important
.text-grey
color: grey

View file

@ -12,7 +12,7 @@ class Admin::BankTransactionsController < AdminController
end end
def bind def bind
if @bank_transaction.bind_invoice(params[:invoice_id]) if @bank_transaction.bind_invoice(params[:invoice_no])
flash[:notice] = I18n.t('record_created') flash[:notice] = I18n.t('record_created')
redirect_to [:admin, @bank_transaction] redirect_to [:admin, @bank_transaction]
else else

View file

@ -28,6 +28,16 @@ class Registrar::InvoicesController < RegistrarController
end end
end end
def cancel
if @invoice.cancel
flash[:notice] = t('record_updated')
redirect_to([:registrar, @invoice])
else
flash.now[:alert] = t('failed_to_update_record')
render :show
end
end
def download_pdf def download_pdf
# render 'pdf', layout: false # render 'pdf', layout: false

View file

@ -25,13 +25,14 @@ class BankTransaction < ActiveRecord::Base
match = description.match(/^[^\d]*(\d+)/) match = description.match(/^[^\d]*(\d+)/)
return unless match return unless match
invoice_id = match[1].to_i invoice_no = match[1].to_i
return unless invoice_id return unless invoice_no
invoice = registrar.invoices.find_by(id: invoice_id) invoice = registrar.invoices.find_by(number: invoice_no)
return unless invoice return unless invoice
return if invoice.binded? return if invoice.binded?
return if invoice.cancelled?
return if invoice.sum != sum return if invoice.sum != sum
create_activity(registrar, invoice) create_activity(registrar, invoice)
@ -39,13 +40,13 @@ class BankTransaction < ActiveRecord::Base
# rubocop: enable Metrics/PerceivedComplexity # rubocop: enable Metrics/PerceivedComplexity
# rubocop: enable Metrics/CyclomaticComplexity # rubocop: enable Metrics/CyclomaticComplexity
def bind_invoice(invoice_id) def bind_invoice(invoice_no)
if binded? if binded?
errors.add(:base, I18n.t('transaction_is_already_binded')) errors.add(:base, I18n.t('transaction_is_already_binded'))
return return
end end
invoice = Invoice.find_by(id: invoice_id) invoice = Invoice.find_by(number: invoice_no)
unless invoice unless invoice
errors.add(:base, I18n.t('invoice_was_not_found')) errors.add(:base, I18n.t('invoice_was_not_found'))
@ -57,6 +58,11 @@ class BankTransaction < ActiveRecord::Base
return return
end end
if invoice.cancelled?
errors.add(:base, I18n.t('cannot_bind_cancelled_invoice'))
return
end
if invoice.sum != sum if invoice.sum != sum
errors.add(:base, I18n.t('invoice_and_transaction_sums_do_not_match')) errors.add(:base, I18n.t('invoice_and_transaction_sums_do_not_match'))
return return

View file

@ -67,6 +67,19 @@ class Invoice < ActiveRecord::Base
"invoice-#{number}.pdf" "invoice-#{number}.pdf"
end end
def cancel
if binded?
errors.add(:base, I18n.t('cannot_cancel_paid_invoice'))
return false
end
self.cancelled_at = Time.zone.now
save
end
def cancelled?
cancelled_at.present?
end
def forward(html) def forward(html)
return false unless valid? return false unless valid?
return false unless billing_email.present? return false unless billing_email.present?

View file

@ -1,5 +1,5 @@
- content_for :actions do - content_for :actions do
= link_to(t('back'), :back, class: 'btn btn-default') = link_to(t('back'), admin_bank_transaction_path(@bank_transaction), class: 'btn btn-default')
= render 'shared/title', name: t(:bank_transaction) = render 'shared/title', name: t(:bank_transaction)
= form_for([:admin, @bank_transaction], html: { class: 'form-horizontal' }) do |f| = form_for([:admin, @bank_transaction], html: { class: 'form-horizontal' }) do |f|

View file

@ -57,5 +57,5 @@
%dl.dl-horizontal %dl.dl-horizontal
%dt{style: 'padding-top: 5px'}= t('binded_invoice') %dt{style: 'padding-top: 5px'}= t('binded_invoice')
%dd %dd
= text_field_tag(:invoice_id, params[:invoice_id], class: 'form-control') = text_field_tag(:invoice_no, params[:invoice_no], class: 'form-control')
= button_tag(t('bind_manually'), class: 'btn btn-primary') = button_tag(t('bind_manually'), class: 'btn btn-primary')

View file

@ -21,9 +21,15 @@
%tr %tr
%td= link_to(x, [:admin, x]) %td= link_to(x, [:admin, x])
%td= link_to(x.buyer_name, admin_registrar_path(x.buyer_id)) %td= link_to(x.buyer_name, admin_registrar_path(x.buyer_id))
%td= l(x.due_date) - if x.cancelled?
%td.text-grey= t('cancelled')
- else
%td= l(x.due_date)
- if x.binded? - if x.binded?
%td= l(x.receipt_date) %td= l(x.receipt_date)
- elsif x.cancelled?
%td.text-grey= t('cancelled')
- else - else
%td.text-danger= t('unpaid') %td.text-danger= t('unpaid')
.row .row

View file

@ -25,9 +25,15 @@
%td= link_to(x, [:registrar, x]) %td= link_to(x, [:registrar, x])
- if x.receipt_date - if x.receipt_date
%td= l(x.receipt_date) %td= l(x.receipt_date)
- elsif x.cancelled?
%td.text-grey= t('cancelled')
- else - else
%td{class: 'text-danger'}= t(:unpaid) %td{class: 'text-danger'}= t(:unpaid)
%td= l(x.due_date)
- if x.cancelled?
%td.text-grey= t('cancelled')
- else
%td= l(x.due_date)
%td= x.sum %td= x.sum
.row .row
.col-md-12 .col-md-12

View file

@ -4,12 +4,21 @@
%dt= t('issue_date') %dt= t('issue_date')
%dd= l(@invoice.created_at) %dd= l(@invoice.created_at)
- if @invoice.cancelled?
%dt= t('cancel_date')
%dd= l(@invoice.cancelled_at)
%dt= t('due_date') %dt= t('due_date')
%dd= l(@invoice.due_date) - if @invoice.cancelled?
%dd.text-grey= t('cancelled')
- else
%dd= l(@invoice.due_date)
%dt= t('receipt_date') %dt= t('receipt_date')
- if @invoice.binded? - if @invoice.binded?
%dd= l(@invoice.receipt_date) %dd= l(@invoice.receipt_date)
- elsif @invoice.cancelled?
%dd.text-grey= t('cancelled')
- else - else
%dd{class: 'text-danger'}= t('unpaid') %dd{class: 'text-danger'}= t('unpaid')

View file

@ -151,12 +151,21 @@
%dt= t('issue_date') %dt= t('issue_date')
%dd= l(@invoice.created_at) %dd= l(@invoice.created_at)
- if @invoice.cancelled?
%dt= t('cancel_date')
%dd= l(@invoice.cancelled_at)
%dt= t('due_date') %dt= t('due_date')
%dd= l(@invoice.due_date) - if @invoice.cancelled?
%dd= t('cancelled')
- else
%dd= l(@invoice.due_date)
%dt= t('receipt_date') %dt= t('receipt_date')
- if @invoice.binded? - if @invoice.binded?
%dd= l(@invoice.receipt_date) %dd= l(@invoice.receipt_date)
- elsif @invoice.cancelled?
%dd= t('cancelled')
- else - else
%dd{class: 'text-danger'}= t('unpaid') %dd{class: 'text-danger'}= t('unpaid')

View file

@ -1,8 +1,11 @@
- content_for :actions do - content_for :actions do
= link_to(t(:download), download_pdf_registrar_invoice_path(@invoice), class: 'btn btn-default') = link_to(t(:download), download_pdf_registrar_invoice_path(@invoice), class: 'btn btn-default')
= link_to(t(:forward_invoice), forward_registrar_invoice_path(@invoice), class: 'btn btn-default') = link_to(t(:forward), forward_registrar_invoice_path(@invoice), class: 'btn btn-default')
= link_to(t(:back), :back, class: 'btn btn-default') - if !@invoice.cancelled? && !@invoice.binded?
= link_to(t(:cancel), cancel_registrar_invoice_path(@invoice), method: :patch, class: 'btn btn-default')
= link_to(t(:back), registrar_invoices_path, class: 'btn btn-default')
= render 'shared/title', name: @invoice.to_s = render 'shared/title', name: @invoice.to_s
= render 'shared/full_errors', object: @invoice
.row .row
.col-md-6= render 'registrar/invoices/partials/details' .col-md-6= render 'registrar/invoices/partials/details'
@ -11,5 +14,7 @@
.col-md-6= render 'registrar/invoices/partials/buyer' .col-md-6= render 'registrar/invoices/partials/buyer'
.row .row
.col-md-12= render 'registrar/invoices/partials/items' .col-md-12= render 'registrar/invoices/partials/items'
.row.semifooter
.col-md-12.text-right= render 'registrar/invoices/partials/banklinks' - if !@invoice.cancelled? && !@invoice.binded?
.row.semifooter
.col-md-12.text-right= render 'registrar/invoices/partials/banklinks'

View file

@ -734,3 +734,8 @@ en:
expiry: 'Expiry' expiry: 'Expiry'
failed_to_create_crt_csr_already_signed: 'Failed to create certificate: CSR is already signed' failed_to_create_crt_csr_already_signed: 'Failed to create certificate: CSR is already signed'
certificates: 'Certificates' certificates: 'Certificates'
cancel: 'Cancel'
cancelled: 'Cancelled'
cancel_date: 'Cancel date'
cannot_cancel_paid_invoice: 'Cannot cancel paid invoice'
cannot_bind_cancelled_invoice: 'Cannot bind cancelled invoice'

View file

@ -21,8 +21,11 @@ Rails.application.routes.draw do
root 'polls#show' root 'polls#show'
resources :invoices do resources :invoices do
get 'download_pdf', on: :member member do
match 'forward', on: :member, via: [:post, :get] get 'download_pdf'
match 'forward', via: [:post, :get]
patch 'cancel'
end
end end
resources :deposits resources :deposits

View file

@ -0,0 +1,5 @@
class AddCancelledAtToInvoice < ActiveRecord::Migration
def change
add_column :invoices, :cancelled_at, :datetime
end
end

View file

@ -11,7 +11,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20150423083308) do ActiveRecord::Schema.define(version: 20150427073517) do
# These are extensions that must be enabled in order to support this database # These are extensions that must be enabled in order to support this database
enable_extension "plpgsql" enable_extension "plpgsql"
@ -297,12 +297,8 @@ ActiveRecord::Schema.define(version: 20150423083308) do
t.integer "legacy_id" t.integer "legacy_id"
t.integer "legacy_registrar_id" t.integer "legacy_registrar_id"
t.integer "legacy_registrant_id" t.integer "legacy_registrant_id"
t.datetime "outzone_at"
t.datetime "delete_at"
end end
add_index "domains", ["delete_at"], name: "index_domains_on_delete_at", using: :btree
add_index "domains", ["outzone_at"], name: "index_domains_on_outzone_at", using: :btree
add_index "domains", ["registrant_id"], name: "index_domains_on_registrant_id", using: :btree add_index "domains", ["registrant_id"], name: "index_domains_on_registrant_id", using: :btree
add_index "domains", ["registrar_id"], name: "index_domains_on_registrar_id", using: :btree add_index "domains", ["registrar_id"], name: "index_domains_on_registrar_id", using: :btree
@ -371,6 +367,7 @@ ActiveRecord::Schema.define(version: 20150423083308) do
t.string "creator_str" t.string "creator_str"
t.string "updator_str" t.string "updator_str"
t.integer "number" t.integer "number"
t.datetime "cancelled_at"
end end
add_index "invoices", ["buyer_id"], name: "index_invoices_on_buyer_id", using: :btree add_index "invoices", ["buyer_id"], name: "index_invoices_on_buyer_id", using: :btree

View file

@ -42,7 +42,7 @@ describe BankTransaction do
invoice = r.issue_prepayment_invoice(200, 'add some money') invoice = r.issue_prepayment_invoice(200, 'add some money')
bt = Fabricate(:bank_transaction, { sum: 240 }) bt = Fabricate(:bank_transaction, { sum: 240 })
bt.bind_invoice(invoice.id) bt.bind_invoice(invoice.number)
invoice.receipt_date.should_not be_blank invoice.receipt_date.should_not be_blank
r.cash_account.balance.should == 240.0 r.cash_account.balance.should == 240.0
@ -53,11 +53,22 @@ describe BankTransaction do
invoice = r.issue_prepayment_invoice(200, 'add some money') invoice = r.issue_prepayment_invoice(200, 'add some money')
bt = Fabricate(:bank_transaction, { sum: 10 }) bt = Fabricate(:bank_transaction, { sum: 10 })
bt.bind_invoice(invoice.id) bt.bind_invoice(invoice.number)
bt.errors.full_messages.should match_array(["Invoice and transaction sums do not match"]) bt.errors.full_messages.should match_array(["Invoice and transaction sums do not match"])
end end
it 'should not bind transaction with cancelled invoice' do
r = Fabricate(:registrar_with_no_account_activities, reference_no: 'RF7086666663')
invoice = r.issue_prepayment_invoice(200, 'add some money')
invoice.cancel
bt = Fabricate(:bank_transaction, { sum: 240 })
bt.bind_invoice(invoice.number)
bt.errors.full_messages.should match_array(["Cannot bind cancelled invoice"])
end
it 'should have one version' do it 'should have one version' do
with_versioning do with_versioning do
@bank_transaction.versions.should == [] @bank_transaction.versions.should == []