class Skr::Invoice

Invoices constitute a demand for payment for goods that have been delivered to a {Customer}. A invoice contains:

* Customer contact information
* An inventory location that goods will be taken from.
* The customer provided {PurchaseOrder} Number
* The Payment Terms that were extended. This will control how much time the Customer has to pay the invoice in full.
* One or more SKUs, the quantity desired for each and the selling price for them.

While an {Invoice} often originates with a {SalesOrder}, it does not have to. Sales that take place in a retail environment where the customer selects the goods and pays for them immediately do not require a sales order record.

Once an invoice is saved, it immediately removes the SKUs from the {SkuLoc} and generates corresponding General Ledger entries debiting the asset account and crediting the customers receivables account.

When payment is received against the Invoice, the receivables account is debited and the payments holding account is credited.

invoice = Invoice.new( customer: Customer.find_by_code("ACME")
invoice.lines.build({ sku: Sku.find_by_code('LABOR'), qty: 1, price: 8.27 })
invoice.save

Public Class Methods

new(attributes = {}) click to toggle source
Calls superclass method
# File lib/skr/models/invoice.rb, line 94
def initialize(attributes = {})
    super
    # date must be set, otherwise things like terms that are based off of it fail
    self.invoice_date ||= Date.today
end

Public Instance Methods

due_date() click to toggle source

@return [DateTime] when the invoice is due

# File lib/skr/models/invoice.rb, line 111
def due_date
    self.terms.due_date_from(invoice_date)
end
fully_paid?() click to toggle source

@return [Boolean] is the invoice paid in full

# File lib/skr/models/invoice.rb, line 106
def fully_paid?
    unpaid_amount <= 0
end
is_locked?() click to toggle source
# File lib/skr/models/invoice.rb, line 115
def is_locked?
    GlPeriod.is_date_locked?(self.invoice_date)
end
total_hours() click to toggle source
# File lib/skr/models/invoice.rb, line 119
def total_hours
    lines.reduce(BigDecimal.new('0')){|t, l|
        l.time_entry ? t + l.qty : t
    }
end
unpaid_amount() click to toggle source

@return [BigDecimal] total - amount_paid

# File lib/skr/models/invoice.rb, line 101
def unpaid_amount
    self.total - self.payments.total
end

Private Instance Methods

apply_payment(pymnt) click to toggle source

set the state if the amount_paid was changed

# File lib/skr/models/invoice.rb, line 128
def apply_payment(pymnt)
    if self.fully_paid? && self.may_mark_paid?
        self.mark_paid!
    elsif self.payments.total > 0 && self.may_mark_partialy_paid?
        self.mark_partialy_paid!
    end
end
ensure_location_matches_so() click to toggle source
# File lib/skr/models/invoice.rb, line 176
def ensure_location_matches_so
    if sales_order && location != sales_order.location
        self.errors.add(:location, "#{location.code} must match location that order was taken on (#{sales_order.location.code})")
    end
end
ensure_unlocked() click to toggle source
# File lib/skr/models/invoice.rb, line 170
def ensure_unlocked
    if is_locked?
        self.errors.add(:invoice_date, "falls on a locked GL Period")
    end
end
set_defaults() click to toggle source
# File lib/skr/models/invoice.rb, line 136
def set_defaults

    if pick_ticket
        self.location    = pick_ticket.location
        self.sales_order = pick_ticket.sales_order
    end

    if sales_order
        self.terms          ||= sales_order.terms
        self.form           ||= sales_order.form
        self.customer         = sales_order.customer
        self.po_num           = sales_order.po_num if self.po_num.blank?
        self.billing_address  = sales_order.billing_address   if self.billing_address.blank?
        self.shipping_address = sales_order.shipping_address  if self.shipping_address.blank?
        if self.options && sales_order.options
            self.options.merge!(sales_order.options)
        else
            self.options = sales_order.options
        end
    end

    if customer_project
        self.customer = customer_project.customer
        self.po_num = customer_project.po_num if self.po_num.blank?
    end

    if customer
        self.form           ||= customer.get_form('invoice')
        self.billing_address  = customer.billing_address   if self.billing_address.blank?
        self.shipping_address = customer.shipping_address if self.shipping_address.blank?
    end

end