lib/xeroizer/models/invoice.rb in xeroizer-2.15.3 vs lib/xeroizer/models/invoice.rb in xeroizer-2.15.5

- old
+ new

@@ -1,10 +1,13 @@ module Xeroizer module Record class InvoiceModel < BaseModel - + # To create a new invoice, use the folowing + # $xero_client.Invoice.build(type: 'ACCREC', ..., contact: {name: 'Foo Bar'},...) + # Note that we are not making an api request to xero just to get the contact + set_permissions :read, :write, :update public # Retrieve the PDF version of the invoice matching the `id`. @@ -42,35 +45,35 @@ set_primary_key :invoice_id set_possible_primary_keys :invoice_id, :invoice_number list_contains_summary_only true - guid :invoice_id - string :invoice_number - string :reference - guid :branding_theme_id - string :url - string :type - date :date - date :due_date - string :status - string :line_amount_types - decimal :sub_total, :calculated => true - decimal :total_tax, :calculated => true - decimal :total, :calculated => true - decimal :amount_due - decimal :amount_paid - decimal :amount_credited - datetime :updated_date_utc, :api_name => 'UpdatedDateUTC' - string :currency_code - datetime :fully_paid_on_date - boolean :sent_to_contact + guid :invoice_id + string :invoice_number + string :reference + guid :branding_theme_id + string :url + string :type + date :date + date :due_date + string :status + string :line_amount_types + decimal :sub_total, :calculated => true + decimal :total_tax, :calculated => true + decimal :total, :calculated => true + decimal :amount_due + decimal :amount_paid + decimal :amount_credited + datetime_utc :updated_date_utc, :api_name => 'UpdatedDateUTC' + string :currency_code + datetime :fully_paid_on_date + boolean :sent_to_contact - belongs_to :contact - has_many :line_items - has_many :payments - has_many :credit_notes + belongs_to :contact + has_many :line_items + has_many :payments + has_many :credit_notes validates_presence_of :date, :due_date, :unless => :new_record? validates_inclusion_of :type, :in => INVOICE_TYPES validates_inclusion_of :status, :in => INVOICE_STATUSES, :unless => :new_record? validates_inclusion_of :line_amount_types, :in => LINE_AMOUNT_TYPES, :unless => :new_record? @@ -105,18 +108,28 @@ # Helper method to check if the invoice is accounts receivable. def accounts_receivable? type == 'ACCREC' end - # Swallow assignment of attributes that should only be calculated automatically. - def sub_total=(value); raise SettingTotalDirectlyNotSupported.new(:sub_total); end - def total_tax=(value); raise SettingTotalDirectlyNotSupported.new(:total_tax); end - def total=(value); raise SettingTotalDirectlyNotSupported.new(:total); end + def sub_total=(sub_total) + @sub_total_is_set = true + attributes[:sub_total] = sub_total + end + + def total_tax=(total_tax) + @total_tax_is_set = true + attributes[:total_tax] = total_tax + end + def total=(total) + @total_is_set = true + attributes[:total] = total + end + # Calculate sub_total from line_items. def sub_total(always_summary = false) - if !always_summary && (new_record? || (!new_record? && line_items && line_items.size > 0)) + if !@sub_total_is_set && not_summary_or_loaded_record(always_summary) sum = (line_items || []).inject(BigDecimal.new('0')) { | sum, line_item | sum + line_item.line_amount } # If the default amount types are inclusive of 'tax' then remove the tax amount from this sub-total. sum -= total_tax if line_amount_types == 'Inclusive' sum @@ -125,25 +138,34 @@ end end # Calculate total_tax from line_items. def total_tax(always_summary = false) - if !always_summary && (new_record? || (!new_record? && line_items && line_items.size > 0)) + if !@total_tax_is_set && not_summary_or_loaded_record(always_summary) (line_items || []).inject(BigDecimal.new('0')) { | sum, line_item | sum + line_item.tax_amount } else attributes[:total_tax] end end # Calculate the total from line_items. def total(always_summary = false) - unless always_summary + if !@total_is_set && not_summary_or_loaded_record(always_summary) sub_total + total_tax else attributes[:total] end end + def not_summary_or_loaded_record(always_summary) + !always_summary && loaded_record? + end + + def loaded_record? + new_record? || + (!new_record? && line_items && line_items.size > 0) + end + # Retrieve the PDF version of this invoice. # @param [String] filename optional filename to store the PDF in instead of returning the data. def pdf(filename = nil) parent.pdf(id, filename) end