Class: StatementOfAccount

Inherits:
ApplicationRecord show all
Includes:
Models::AccountingDocumentTransmittable, Models::Auditable
Defined in:
app/models/statement_of_account.rb

Overview

== Schema Information

Table name: statement_of_accounts
Database name: primary

id :integer not null, primary key
currency :string(255)
open_amount :decimal(12, 2)
transmission_error :text
transmission_state :string(255)
uploads_count :integer
created_at :datetime
updated_at :datetime
customer_id :integer

Indexes

index_statement_of_accounts_on_customer_id (customer_id)
index_statement_of_accounts_on_transmission_state (transmission_state)

Constant Summary

Constants included from Models::Auditable

Models::Auditable::ALWAYS_IGNORED

Constants included from Models::Schedulable

Models::Schedulable::SIMPLE_FORM_OPTIONS

Instance Attribute Summary collapse

Belongs to collapse

Methods included from Models::Auditable

#creator, #updater

Has many collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Models::AccountingDocumentTransmittable

#can_be_transmitted?, #fallback_notification_channel_type, #notification_channel_sort_order, #notification_channel_types, #notification_channels, #own_notification_channel_type, #post_communication_exception_hook, #post_communication_sent_hook, #primary_transmission_contact, #primary_transmission_contact_point_id, #transmission_contact_points

Methods included from Models::Auditable

#all_skipped_columns, #audit_reference_data, #should_not_save_version, #stamp_record

Methods inherited from ApplicationRecord

ransackable_associations, ransackable_attributes, ransackable_scopes, ransortable_attributes, #to_relation

Methods included from Models::Schedulable

config

Methods included from Models::AfterCommittable

#after_commit

Methods included from Models::EventPublishable

#publish_event

Instance Attribute Details

#customer_idInteger (readonly)

Returns:

  • (Integer)


34
# File 'app/models/statement_of_account.rb', line 34

validates :customer_id, presence: true

Class Method Details

.generate_monthly_statementsvoid

This method returns an undefined value.



124
125
126
127
128
129
# File 'app/models/statement_of_account.rb', line 124

def self.generate_monthly_statements
  customer_ids = Customer.where(send_statement: true).ids
  customer_ids.each do |customer_id|
    StatementOfAccountGenerationWorker.perform_async(customer_id)
  end
end

.generate_pdf(customer, split_by_currency = false) ⇒ void

Parameters:

  • customer (Object)
  • split_by_currency (Object) (defaults to: false)
  • customer (Object)
  • split_by_currency (Object) (defaults to: false)

Returns:

  • (void)
  • (void)


81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'app/models/statement_of_account.rb', line 81

def self.generate_pdf(customer, split_by_currency = false)
  results = StatementOfAccount.results(customer, true)
  uploads = []
  if split_by_currency == true
    # need to generate a statement for each currency
    results.each do |currency, res|
      if res.empty?
        nil
      else
        soa = StatementOfAccount.create(currency:, customer_id: customer.id, open_amount: res.sum { |r| BigDecimal(r.open_amount) })
        soa.transmit
        pdf = Statement::PdfGenerator.new.process(soa, { currency => res }).pdf
        path = Upload.temp_location(soa.file_name)
        File.open(path, 'wb') do |file|
          file.write pdf
          file.flush
          file.fsync
        end
        upload = Upload.uploadify(path, 'statement_of_account_pdf', soa, soa.file_name(true))
        uploads << upload
      end
    end
  elsif results.empty?
    # need to combine into one statement
    soa = nil
  else
    soa = StatementOfAccount.create(currency: 'ALL', customer_id: customer.id, open_amount: results.sum { |_currency, res| res.sum { |r| BigDecimal(r.open_amount) } })
    soa.transmit
    pdf = Statement::PdfGenerator.new.process(soa, results).pdf
    path = Upload.temp_location(soa.file_name)
    File.open(path, 'wb') do |file|
      file.write pdf
      file.flush
      file.fsync
    end
    upload = Upload.uploadify(path, 'statement_of_account_pdf', soa, soa.file_name(true))
    uploads << upload
  end

  soa
end

.results(customer, include_ship_to = false) ⇒ void

Parameters:

  • customer (Object)
  • include_ship_to (Object) (defaults to: false)
  • customer (Object)
  • include_ship_to (Object) (defaults to: false)

Returns:

  • (void)
  • (void)


57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'app/models/statement_of_account.rb', line 57

def self.results(customer, include_ship_to = false)
  start_date = Date.current - 4.years
  end_date = Date.current + 1.year
  invoices = Invoice.where(state: 'unpaid').where(due_date: start_date..end_date).where.not(total: 0)
                    .select("customer_id, billing_customer_id, 'INVOICE' as doc_type, reference_number, po_number, terms, gl_date, due_date, (invoices.total - coalesce((select sum(rd.amount)+sum(rd.discount)+sum(rd.write_off) as receipts_total from receipt_details rd where rd.state <> 'voided' and rd.invoice_id = invoices.id),0)) as open_amount, currency")
  invoices = include_ship_to == true ? invoices.where.any_of({ billing_customer_id: customer.id }, { customer_id: customer.id }) : invoices.where(billing_customer_id: customer.id)
  credit_memos = CreditMemo.where(state: %w[printed partially_offset]).where(document_date: start_date..end_date).where.not(total: 0)
                           .select("customer_id, billing_customer_id, 'CREDIT' as doc_type, reference_number, original_po_number as po_number, (select p.terms from parties p where p.id = credit_memos.customer_id) as terms, gl_date, document_date as due_date, credit_memos.total - (coalesce((select sum(amount) from receipt_details where credit_memo_id = credit_memos.id and state <> 'voided'),0)-coalesce((select sum(amount) from outgoing_payment_items where credit_memo_id = credit_memos.id and state = 'applied'),0)) as open_amount, currency")
  credit_memos = include_ship_to == true ? credit_memos.where.any_of({ billing_customer_id: customer.id }, { customer_id: customer.id }) : credit_memos.where(billing_customer_id: customer.id)
  receipts = Receipt.where(state: %w[unapplied partially_applied]).where(receipt_date: start_date..end_date).where(customer_id: customer.id).where.not(amount: 0)
                    .select("customer_id, customer_id as billing_customer_id, 'PAYMENT' as doc_type, reference as reference_number, null as po_number, (select p.terms from parties p where p.id = receipts.customer_id) as terms, gl_date as gl_date, receipt_date as due_date, (receipts.amount - coalesce((select sum(rd.amount)+sum(rd.discount)+sum(rd.write_off) as receipts_total from receipt_details rd where rd.state <> 'voided' and rd.receipt_id = receipts.id),0)) * -1 as open_amount, currency")
  statement_results = invoices + credit_memos + receipts
  statement_results = statement_results.group_by(&:currency)
  sorted_statement_results = {}
  statement_results.each { |currency, results| sorted_statement_results[currency] = results.sort_by { |a| Date.strptime(a.due_date.to_s, '%Y-%m-%d') } }
  sorted_statement_results
end

Instance Method Details

#billing_address_idvoid

This method returns an undefined value.



47
48
49
# File 'app/models/statement_of_account.rb', line 47

def billing_address_id
  customer.billing_address.party_id
end

#billing_customervoid

This method returns an undefined value.



42
43
44
# File 'app/models/statement_of_account.rb', line 42

def billing_customer
  customer.billing_address.party
end

#communicationsActiveRecord::Relation<Communication>

Returns:



31
# File 'app/models/statement_of_account.rb', line 31

has_many :communications, -> { order(:id).reverse_order }, as: :resource, dependent: :nullify

#customerCustomer?

Returns:



26
# File 'app/models/statement_of_account.rb', line 26

belongs_to :customer, optional: true

#file_name(with_extension = true) ⇒ void

Parameters:

  • with_extension (Object) (defaults to: true)
  • with_extension (Object) (defaults to: true)

Returns:

  • (void)
  • (void)


140
141
142
# File 'app/models/statement_of_account.rb', line 140

def file_name(with_extension = true)
  "Statement_of_Account_#{customer.id}_#{currency}#{'.pdf' if with_extension}"
end

#reference_numbervoid

This method returns an undefined value.



132
133
134
# File 'app/models/statement_of_account.rb', line 132

def reference_number
  "SOA#{id}"
end

#to_sString

Returns:

  • (String)


37
38
39
# File 'app/models/statement_of_account.rb', line 37

def to_s
  "Statement Of Account #{id}"
end

#uploadsActiveRecord::Relation<Upload>

Returns:

  • (ActiveRecord::Relation<Upload>)


29
# File 'app/models/statement_of_account.rb', line 29

has_many :uploads, as: :resource, dependent: :destroy