mirror of
https://github.com/internetee/registry.git
synced 2025-07-24 11:38:30 +02:00
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:
parent
d86ec026e3
commit
a97728c0f3
65 changed files with 758 additions and 341 deletions
|
@ -33,13 +33,8 @@ module Admin
|
|||
end
|
||||
|
||||
def cancel
|
||||
if @invoice.cancel
|
||||
flash[:notice] = t(:record_updated)
|
||||
redirect_to([:admin, @invoice])
|
||||
else
|
||||
flash.now[:alert] = t(:failed_to_update_record)
|
||||
render :show
|
||||
end
|
||||
@invoice.cancel
|
||||
redirect_to [:admin, @invoice], notice: t('.cancelled')
|
||||
end
|
||||
|
||||
def forward
|
||||
|
|
|
@ -6,8 +6,7 @@ class Registrar
|
|||
|
||||
def index
|
||||
params[:q] ||= {}
|
||||
invoices = current_registrar_user.registrar.invoices
|
||||
.includes(:invoice_items, :account_activity)
|
||||
invoices = current_registrar_user.registrar.invoices.includes(:items, :account_activity)
|
||||
|
||||
normalize_search_parameters do
|
||||
@q = invoices.search(params[:q])
|
||||
|
@ -35,13 +34,8 @@ class Registrar
|
|||
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
|
||||
@invoice.cancel
|
||||
redirect_to [:registrar, @invoice], notice: t('.cancelled')
|
||||
end
|
||||
|
||||
def download_pdf
|
||||
|
@ -58,18 +52,7 @@ class Registrar
|
|||
def normalize_search_parameters
|
||||
params[:q][:total_gteq].gsub!(',', '.') if params[:q][:total_gteq]
|
||||
params[:q][:total_lteq].gsub!(',', '.') if params[:q][:total_lteq]
|
||||
|
||||
ca_cache = params[:q][:due_date_lteq]
|
||||
begin
|
||||
end_time = params[:q][:due_date_lteq].try(:to_date)
|
||||
params[:q][:due_date_lteq] = end_time.try(:end_of_day)
|
||||
rescue
|
||||
logger.warn('Invalid date')
|
||||
end
|
||||
|
||||
yield
|
||||
|
||||
params[:q][:due_date_lteq] = ca_cache
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -29,7 +29,7 @@ class Registrar
|
|||
if @payment.valid_response_from_intermediary? && @payment.settled_payment?
|
||||
@payment.complete_transaction
|
||||
|
||||
if invoice.binded?
|
||||
if invoice.paid?
|
||||
flash[:notice] = t(:pending_applied)
|
||||
else
|
||||
flash[:alert] = t(:something_wrong)
|
||||
|
|
|
@ -41,9 +41,7 @@ class BankTransaction < ActiveRecord::Base
|
|||
return unless registrar
|
||||
return unless invoice_num
|
||||
return unless invoice
|
||||
|
||||
return if invoice.binded?
|
||||
return if invoice.cancelled?
|
||||
return unless invoice.payable?
|
||||
|
||||
return if invoice.total != sum
|
||||
create_activity(registrar, invoice)
|
||||
|
@ -62,7 +60,7 @@ class BankTransaction < ActiveRecord::Base
|
|||
return
|
||||
end
|
||||
|
||||
if invoice.binded?
|
||||
if invoice.paid?
|
||||
errors.add(:base, I18n.t('invoice_is_already_binded'))
|
||||
return
|
||||
end
|
||||
|
|
28
app/models/concerns/invoice/cancellable.rb
Normal file
28
app/models/concerns/invoice/cancellable.rb
Normal file
|
@ -0,0 +1,28 @@
|
|||
module Concerns
|
||||
module Invoice
|
||||
module Cancellable
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
scope :non_cancelled, -> { where(cancelled_at: nil) }
|
||||
end
|
||||
|
||||
def cancellable?
|
||||
unpaid? && not_cancelled?
|
||||
end
|
||||
|
||||
def cancel
|
||||
raise 'Invoice cannot be cancelled' unless cancellable?
|
||||
update!(cancelled_at: Time.zone.now)
|
||||
end
|
||||
|
||||
def cancelled?
|
||||
cancelled_at
|
||||
end
|
||||
|
||||
def not_cancelled?
|
||||
!cancelled?
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
28
app/models/concerns/invoice/payable.rb
Normal file
28
app/models/concerns/invoice/payable.rb
Normal file
|
@ -0,0 +1,28 @@
|
|||
module Concerns
|
||||
module Invoice
|
||||
module Payable
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
scope :unpaid, -> { where('id NOT IN (SELECT invoice_id FROM account_activities WHERE' \
|
||||
' invoice_id IS NOT NULL)') }
|
||||
end
|
||||
|
||||
def payable?
|
||||
unpaid? && not_cancelled?
|
||||
end
|
||||
|
||||
def paid?
|
||||
account_activity
|
||||
end
|
||||
|
||||
def receipt_date
|
||||
account_activity.created_at.to_date
|
||||
end
|
||||
|
||||
def unpaid?
|
||||
!paid?
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -3,7 +3,7 @@ class Directo < ActiveRecord::Base
|
|||
belongs_to :item, polymorphic: true
|
||||
|
||||
def self.send_receipts
|
||||
new_trans = Invoice.where(in_directo: false).where(cancelled_at: nil)
|
||||
new_trans = Invoice.where(in_directo: false).non_cancelled
|
||||
total = new_trans.count
|
||||
counter = 0
|
||||
Rails.logger.info("[DIRECTO] Will try to send #{total} invoices")
|
||||
|
@ -26,7 +26,7 @@ class Directo < ActiveRecord::Base
|
|||
xml.invoice(
|
||||
"SalesAgent" => Setting.directo_sales_agent,
|
||||
"Number" => num,
|
||||
"InvoiceDate" => invoice.created_at.strftime("%Y-%m-%d"),
|
||||
"InvoiceDate" => invoice.issue_date.strftime("%Y-%m-%d"),
|
||||
"PaymentTerm" => Setting.directo_receipt_payment_term,
|
||||
"Currency" => invoice.currency,
|
||||
"CustomerCode"=> invoice.buyer.accounting_customer_code
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
class Invoice < ActiveRecord::Base
|
||||
include Versions
|
||||
include Concerns::Invoice::Cancellable
|
||||
include Concerns::Invoice::Payable
|
||||
|
||||
belongs_to :seller, class_name: 'Registrar'
|
||||
belongs_to :buyer, class_name: 'Registrar'
|
||||
has_one :account_activity
|
||||
has_many :invoice_items
|
||||
has_many :items, class_name: 'InvoiceItem', dependent: :destroy
|
||||
has_many :directo_records, as: :item, class_name: 'Directo'
|
||||
|
||||
accepts_nested_attributes_for :invoice_items
|
||||
accepts_nested_attributes_for :items
|
||||
|
||||
scope :unbinded, lambda {
|
||||
where('id NOT IN (SELECT invoice_id FROM account_activities where invoice_id IS NOT NULL)')
|
||||
}
|
||||
scope :all_columns, ->{select("invoices.*")}
|
||||
scope :sort_due_date_column, ->{all_columns.select("CASE WHEN invoices.cancelled_at is not null THEN
|
||||
(invoices.cancelled_at + interval '100 year') ELSE
|
||||
|
@ -24,11 +24,14 @@ class Invoice < ActiveRecord::Base
|
|||
scope :sort_by_sort_receipt_date_asc, ->{sort_receipt_date_column.order("sort_receipt_date ASC")}
|
||||
scope :sort_by_sort_receipt_date_desc, ->{sort_receipt_date_column.order("sort_receipt_date DESC")}
|
||||
|
||||
scope :overdue, -> { unpaid.non_cancelled.where('due_date < ?', Time.zone.today) }
|
||||
|
||||
attr_accessor :billing_email
|
||||
validates :billing_email, email_format: { message: :invalid }, allow_blank: true
|
||||
|
||||
validates :issue_date, presence: true
|
||||
validates :due_date, :currency, :seller_name,
|
||||
:seller_iban, :buyer_name, :invoice_items, presence: true
|
||||
:seller_iban, :buyer_name, :items, presence: true
|
||||
validates :vat_rate, numericality: { greater_than_or_equal_to: 0, less_than: 100 },
|
||||
allow_nil: true
|
||||
|
||||
|
@ -56,35 +59,6 @@ class Invoice < ActiveRecord::Base
|
|||
false
|
||||
end
|
||||
|
||||
class << self
|
||||
def cancel_overdue_invoices
|
||||
STDOUT << "#{Time.zone.now.utc} - Cancelling overdue invoices\n" unless Rails.env.test?
|
||||
|
||||
cr_at = Time.zone.now - Setting.days_to_keep_overdue_invoices_active.days
|
||||
invoices = Invoice.unbinded.where(
|
||||
'due_date < ? AND cancelled_at IS NULL', cr_at
|
||||
)
|
||||
|
||||
unless Rails.env.test?
|
||||
invoices.each do |m|
|
||||
STDOUT << "#{Time.zone.now.utc} Invoice.cancel_overdue_invoices: ##{m.id}\n"
|
||||
end
|
||||
end
|
||||
|
||||
count = invoices.update_all(cancelled_at: Time.zone.now)
|
||||
|
||||
STDOUT << "#{Time.zone.now.utc} - Successfully cancelled #{count} overdue invoices\n" unless Rails.env.test?
|
||||
end
|
||||
end
|
||||
|
||||
def binded?
|
||||
account_activity.present?
|
||||
end
|
||||
|
||||
def receipt_date
|
||||
account_activity.try(:created_at)
|
||||
end
|
||||
|
||||
def to_s
|
||||
I18n.t('invoice_no', no: number)
|
||||
end
|
||||
|
@ -119,25 +93,6 @@ class Invoice < ActiveRecord::Base
|
|||
"invoice-#{number}.pdf"
|
||||
end
|
||||
|
||||
def cancel
|
||||
if binded?
|
||||
errors.add(:base, I18n.t('cannot_cancel_paid_invoice'))
|
||||
return false
|
||||
end
|
||||
|
||||
if cancelled?
|
||||
errors.add(:base, I18n.t('cannot_cancel_cancelled_invoice'))
|
||||
return false
|
||||
end
|
||||
|
||||
self.cancelled_at = Time.zone.now
|
||||
save
|
||||
end
|
||||
|
||||
def cancelled?
|
||||
cancelled_at.present?
|
||||
end
|
||||
|
||||
def forward(html)
|
||||
return false unless valid?
|
||||
return false unless billing_email.present?
|
||||
|
@ -146,12 +101,8 @@ class Invoice < ActiveRecord::Base
|
|||
true
|
||||
end
|
||||
|
||||
def items
|
||||
invoice_items
|
||||
end
|
||||
|
||||
def subtotal
|
||||
invoice_items.map(&:item_sum_without_vat).reduce(:+)
|
||||
items.map(&:item_sum_without_vat).reduce(:+)
|
||||
end
|
||||
|
||||
def vat_amount
|
||||
|
@ -164,6 +115,10 @@ class Invoice < ActiveRecord::Base
|
|||
read_attribute(:total)
|
||||
end
|
||||
|
||||
def each
|
||||
items.each { |item| yield item }
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def apply_default_vat_rate
|
||||
|
|
|
@ -3,6 +3,6 @@ class InvoiceItem < ActiveRecord::Base
|
|||
belongs_to :invoice
|
||||
|
||||
def item_sum_without_vat
|
||||
(amount * price).round(2)
|
||||
(price * quantity).round(2)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -51,8 +51,8 @@ class Registrar < ActiveRecord::Base
|
|||
|
||||
def issue_prepayment_invoice(amount, description = nil)
|
||||
invoices.create(
|
||||
due_date: (Time.zone.now.to_date + Setting.days_to_keep_invoices_active.days).end_of_day,
|
||||
payment_term: 'prepayment',
|
||||
issue_date: Time.zone.today,
|
||||
due_date: (Time.zone.now + Setting.days_to_keep_invoices_active.days).to_date,
|
||||
description: description,
|
||||
currency: 'EUR',
|
||||
seller_name: Setting.registry_juridical_name,
|
||||
|
@ -82,11 +82,11 @@ class Registrar < ActiveRecord::Base
|
|||
buyer_url: website,
|
||||
buyer_email: email,
|
||||
reference_no: reference_no,
|
||||
invoice_items_attributes: [
|
||||
items_attributes: [
|
||||
{
|
||||
description: 'prepayment',
|
||||
unit: 'piece',
|
||||
amount: 1,
|
||||
quantity: 1,
|
||||
price: amount
|
||||
}
|
||||
]
|
||||
|
|
33
app/services/overdue_invoice_canceller.rb
Normal file
33
app/services/overdue_invoice_canceller.rb
Normal file
|
@ -0,0 +1,33 @@
|
|||
class OverdueInvoiceCanceller
|
||||
attr_reader :invoices
|
||||
attr_reader :delay
|
||||
|
||||
def initialize(invoices: Invoice.overdue, delay: self.class.delay)
|
||||
@invoices = invoices
|
||||
@delay = delay
|
||||
end
|
||||
|
||||
def self.default_delay
|
||||
30.days
|
||||
end
|
||||
|
||||
def self.delay
|
||||
Setting.days_to_keep_overdue_invoices_active&.days || default_delay
|
||||
end
|
||||
|
||||
def cancel
|
||||
invoices.each do |invoice|
|
||||
next unless cancellable?(invoice)
|
||||
|
||||
invoice.cancel
|
||||
yield invoice if block_given?
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def cancellable?(invoice)
|
||||
due_date_with_delay = invoice.due_date + delay
|
||||
due_date_with_delay.past?
|
||||
end
|
||||
end
|
|
@ -61,7 +61,7 @@
|
|||
%th{class: 'col-xs-2'}
|
||||
= sort_link(@q, 'activity_type')
|
||||
%th{class: 'col-xs-3'}
|
||||
= sort_link(@q, 'created_at', t(:receipt_date))
|
||||
= sort_link(@q, 'created_at', AccountActivity.human_attribute_name(:created_at))
|
||||
%th{class: 'col-xs-2'}
|
||||
= sort_link(@q, 'sum')
|
||||
%tbody
|
||||
|
|
|
@ -16,18 +16,18 @@
|
|||
%th{class: 'col-xs-3'}
|
||||
= sort_link(@q, :sort_receipt_date, "Receipt date")
|
||||
%tbody
|
||||
- @invoices.each do |x|
|
||||
- @invoices.each do |invoice|
|
||||
%tr
|
||||
%td= link_to(x, [:admin, x])
|
||||
%td= link_to(x.buyer_name, admin_registrar_path(x.buyer_id))
|
||||
- if x.cancelled?
|
||||
%td= link_to(invoice, [:admin, invoice])
|
||||
%td= link_to(invoice.buyer_name, admin_registrar_path(invoice.buyer_id))
|
||||
- if invoice.cancelled?
|
||||
%td.text-grey= t(:cancelled)
|
||||
- else
|
||||
%td= l(x.due_date, format: :date_long)
|
||||
%td= l invoice.due_date
|
||||
|
||||
- if x.binded?
|
||||
%td= l(x.receipt_date, format: :date_long)
|
||||
- elsif x.cancelled?
|
||||
- if invoice.paid?
|
||||
%td= l invoice.receipt_date
|
||||
- elsif invoice.cancelled?
|
||||
%td.text-grey= t(:cancelled)
|
||||
- else
|
||||
%td.text-danger= t(:unpaid)
|
||||
|
|
|
@ -4,11 +4,11 @@
|
|||
= @invoice
|
||||
.col-sm-8
|
||||
%h1.text-right.text-center-xs
|
||||
- unless @invoice.binded?
|
||||
- if @invoice.unpaid?
|
||||
= link_to(t(:payment_received), new_admin_bank_statement_path(invoice_id: @invoice.id), class: 'btn btn-default')
|
||||
= link_to(t(:download), admin_invoice_download_pdf_path(@invoice), class: 'btn btn-default')
|
||||
= link_to(t(:forward), admin_invoice_forward_path(@invoice), class: 'btn btn-default')
|
||||
- if !@invoice.cancelled? && !@invoice.binded?
|
||||
- if @invoice.cancellable?
|
||||
= link_to(t(:cancel), cancel_admin_invoice_path(@invoice), method: :patch, class: 'btn btn-warning')
|
||||
= link_to(t(:back), admin_invoices_path, class: 'btn btn-default')
|
||||
%hr
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
%th{class: 'col-xs-2'}
|
||||
= sort_link(@q, 'activity_type')
|
||||
%th{class: 'col-xs-3'}
|
||||
= sort_link(@q, 'created_at', t(:receipt_date))
|
||||
= sort_link(@q, 'created_at', AccountActivity.human_attribute_name(:created_at))
|
||||
%th{class: 'col-xs-2'}
|
||||
= sort_link(@q, 'sum')
|
||||
%tbody
|
||||
|
|
|
@ -52,22 +52,22 @@
|
|||
%thead
|
||||
%tr
|
||||
%th{class: 'col-xs-3'}= t(:invoice)
|
||||
%th{class: 'col-xs-3'}= t(:receipt_date)
|
||||
%th{class: 'col-xs-3'}= Invoice.human_attribute_name :receipt_date
|
||||
%th{class: 'col-xs-3'}= t(:due_date)
|
||||
%th{class: 'col-xs-3'}= t(:total)
|
||||
%tbody
|
||||
- @invoices.each do |x|
|
||||
%tr
|
||||
%td= link_to(x, [:registrar, x])
|
||||
- if x.receipt_date
|
||||
%td= l(x.receipt_date, format: :date_long)
|
||||
- elsif x.cancelled?
|
||||
- @invoices.each do |invoice|
|
||||
%tr.invoice
|
||||
%td= link_to(invoice, [:registrar, invoice])
|
||||
- if invoice.paid?
|
||||
%td= l invoice.receipt_date
|
||||
- elsif invoice.cancelled?
|
||||
%td.text-grey= t(:cancelled)
|
||||
- else
|
||||
%td{class: 'text-danger'}= t(:unpaid)
|
||||
|
||||
%td= l(x.due_date, format: :date_long)
|
||||
%td= currency(x.total)
|
||||
%td= l invoice.due_date
|
||||
%td= currency(invoice.total)
|
||||
.row
|
||||
.col-md-12
|
||||
= paginate @invoices
|
||||
|
|
|
@ -2,28 +2,28 @@
|
|||
%hr
|
||||
%dl.dl-horizontal
|
||||
%dt= t(:issue_date)
|
||||
%dd= l(@invoice.created_at, format: :date_long)
|
||||
%dd= l @invoice.issue_date
|
||||
|
||||
- if @invoice.cancelled?
|
||||
%dt= t(:cancel_date)
|
||||
%dd= l(@invoice.cancelled_at, format: :date_long)
|
||||
%dt= Invoice.human_attribute_name :cancelled_at
|
||||
%dd= l @invoice.cancelled_at
|
||||
|
||||
%dt= t(:due_date)
|
||||
- if @invoice.cancelled?
|
||||
%dd.text-grey= t(:cancelled)
|
||||
- else
|
||||
%dd= l(@invoice.due_date, format: :date_long)
|
||||
%dd= l @invoice.due_date
|
||||
|
||||
%dt= t(:receipt_date)
|
||||
- if @invoice.binded?
|
||||
%dd= l(@invoice.receipt_date, format: :date_long)
|
||||
%dt= Invoice.human_attribute_name :receipt_date
|
||||
- if @invoice.paid?
|
||||
%dd= l @invoice.receipt_date
|
||||
- elsif @invoice.cancelled?
|
||||
%dd.text-grey= t(:cancelled)
|
||||
- else
|
||||
%dd{class: 'text-danger'}= t(:unpaid)
|
||||
|
||||
%dt= t(:payment_term)
|
||||
%dd= t(@invoice.payment_term)
|
||||
%dd Prepayment
|
||||
|
||||
%dt= t(:invoice_number)
|
||||
%dd= @invoice.number
|
||||
|
|
|
@ -6,17 +6,17 @@
|
|||
%tr
|
||||
%th{class: 'col-xs-4'}= t(:description)
|
||||
%th{class: 'col-xs-2'}= t(:unit)
|
||||
%th{class: 'col-xs-2'}= t(:amount)
|
||||
%th{class: 'col-xs-2'}= InvoiceItem.human_attribute_name :quantity
|
||||
%th{class: 'col-xs-2'}= t(:price)
|
||||
%th{class: 'col-xs-2'}= t(:total)
|
||||
%tbody
|
||||
- @invoice.items.each do |x|
|
||||
- @invoice.each do |invoice_item|
|
||||
%tr
|
||||
%td= t(x.description)
|
||||
%td= x.unit
|
||||
%td= currency(x.amount)
|
||||
%td= currency(x.price)
|
||||
%td= currency(x.item_sum_without_vat)
|
||||
%td= invoice_item.description
|
||||
%td= invoice_item.unit
|
||||
%td= invoice_item.quantity
|
||||
%td= currency(invoice_item.price)
|
||||
%td= currency(invoice_item.item_sum_without_vat)
|
||||
%tfoot
|
||||
%tr
|
||||
%th{colspan: 3}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
/ %dd= t(@invoice.document_name)
|
||||
|
||||
%dt= t(:issue_date)
|
||||
%dd= l(@invoice.created_at)
|
||||
%dd= l(@invoice.date)
|
||||
|
||||
%dt= t(:due_date)
|
||||
%dd= l(@invoice.due_date)
|
||||
|
|
|
@ -149,21 +149,21 @@
|
|||
%hr
|
||||
%dl.dl-horizontal
|
||||
%dt= t(:issue_date)
|
||||
%dd= l(@invoice.created_at, format: :date_long)
|
||||
%dd= l @invoice.issue_date
|
||||
|
||||
- if @invoice.cancelled?
|
||||
%dt= t(:cancel_date)
|
||||
%dd= l(@invoice.cancelled_at, format: :date_long)
|
||||
%dt= Invoice.human_attribute_name :cancelled_at
|
||||
%dd= l @invoice.cancelled_at,
|
||||
|
||||
%dt= t(:due_date)
|
||||
- if @invoice.cancelled?
|
||||
%dd= t(:cancelled)
|
||||
- else
|
||||
%dd= l(@invoice.due_date, format: :date_long)
|
||||
%dd= l @invoice.due_date
|
||||
|
||||
%dt= t(:receipt_date)
|
||||
- if @invoice.binded?
|
||||
%dd= l(@invoice.receipt_date, format: :date_long)
|
||||
%dt= Invoice.human_attribute_name :receipt_date
|
||||
- if @invoice.paid?
|
||||
%dd= l @invoice.receipt_date
|
||||
- elsif @invoice.cancelled?
|
||||
%dd= t(:cancelled)
|
||||
- else
|
||||
|
@ -173,7 +173,7 @@
|
|||
%dd= @invoice.seller_contact_name
|
||||
|
||||
%dt= t(:payment_term)
|
||||
%dd= t(@invoice.payment_term)
|
||||
%dd Prepayment
|
||||
|
||||
%dt= t(:invoice_number)
|
||||
%dd= @invoice.number
|
||||
|
@ -224,17 +224,17 @@
|
|||
%tr
|
||||
%th{class: 'col-xs-4'}= t(:description)
|
||||
%th{class: 'col-xs-2'}= t(:unit)
|
||||
%th{class: 'col-xs-1'}= t(:amount)
|
||||
%th{class: 'col-xs-1'}= InvoiceItem.human_attribute_name :quantity
|
||||
%th{class: 'col-xs-3'}= t(:price)
|
||||
%th{class: 'col-xs-2'}= t(:total)
|
||||
%tbody
|
||||
- @invoice.items.each do |x|
|
||||
- @invoice.each do |invoice_item|
|
||||
%tr
|
||||
%td= t(x.description)
|
||||
%td= x.unit
|
||||
%td= currency(x.amount)
|
||||
%td= currency(x.price)
|
||||
%td= "#{currency(x.item_sum_without_vat)} #{@invoice.currency}"
|
||||
%td= invoice_item.description
|
||||
%td= invoice_item.unit
|
||||
%td= invoice_item.quantity
|
||||
%td= currency(invoice_item.price)
|
||||
%td= "#{currency(invoice_item.item_sum_without_vat)} #{@invoice.currency}"
|
||||
%tfoot
|
||||
%tr
|
||||
%th{colspan: 3}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
- content_for :actions do
|
||||
= link_to(t(:download), download_pdf_registrar_invoice_path(@invoice), class: 'btn btn-default')
|
||||
= link_to(t(:forward), forward_registrar_invoice_path(@invoice), class: 'btn btn-default')
|
||||
- if !@invoice.cancelled? && !@invoice.binded?
|
||||
- if @invoice.cancellable?
|
||||
= link_to(t(:cancel), cancel_registrar_invoice_path(@invoice), method: :patch, class: 'btn btn-warning')
|
||||
= link_to(t(:back), registrar_invoices_path, class: 'btn btn-default')
|
||||
= render 'shared/title', name: @invoice.to_s
|
||||
|
@ -15,6 +15,6 @@
|
|||
.row
|
||||
.col-md-12= render 'registrar/invoices/partials/items'
|
||||
|
||||
- if !@invoice.cancelled? && !@invoice.binded?
|
||||
- if @invoice.payable?
|
||||
.row.semifooter
|
||||
.col-md-6-offset-6.text-right= render 'registrar/invoices/partials/banklinks', locals: { payment_channels: PaymentOrders::PAYMENT_METHODS }
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue