Class: OutgoingPayment
Overview
== Schema Information
Table name: outgoing_payments
Database name: primary
id :integer not null, primary key
amount :decimal(10, 2)
approved_at :datetime
category :string(255)
check_state :string(255)
currency :string(255)
exchange_rate :float
payment_date :date
print_reminder_sent :boolean default(FALSE)
reference_number :string(255) not null
remark :text
reversal_date :date
review_request_sent :boolean default(FALSE)
state :string(255)
created_at :datetime
updated_at :datetime
approved_by_id :integer
bank_account_id :integer
company_id :integer
creator_id :integer
job_id :string(255)
mailing_address_id :integer
supplier_id :integer
updater_id :integer
Indexes
category_state (category,state)
index_outgoing_payments_on_amount (amount)
index_outgoing_payments_on_bank_account_id (bank_account_id)
index_outgoing_payments_on_check_state (check_state)
index_outgoing_payments_on_company_id (company_id)
index_outgoing_payments_on_currency (currency)
index_outgoing_payments_on_job_id (job_id)
index_outgoing_payments_on_mailing_address_id (mailing_address_id)
index_outgoing_payments_on_payment_date (payment_date)
index_outgoing_payments_on_reference_number (reference_number)
index_outgoing_payments_on_state (state)
index_outgoing_payments_on_supplier_id (supplier_id)
Constant Summary
collapse
- CATEGORIES =
%w[ach cash check debit_card e_billpay non_cash paypal wire_transfer].freeze
- DEFAULT_BANK_ACCOUNTS =
default bank account per country and payment method, using => instead of : to force it to use strings for the keys
{
1 => {
'ach' => 1,
'check' => 1,
'debit_card' => 1,
'e_billpay' => 1,
'paypal' => 7,
'wire_transfer' => 1
},
2 => {
'ach' => 2,
'check' => 2,
'debit_card' => 2,
'e_billpay' => 2,
'paypal' => 8,
'wire_transfer' => 2
},
3 => {},
4 => {}
}.freeze
Models::Auditable::ALWAYS_IGNORED
Instance Attribute Summary collapse
#creator, #updater
Class Method Summary
collapse
Instance Method Summary
collapse
#all_skipped_columns, #audit_reference_data, #should_not_save_version, #stamp_record
ransackable_associations, ransackable_attributes, ransackable_scopes, ransortable_attributes, #to_relation
#publish_event
Instance Attribute Details
#amount ⇒ Object
86
|
# File 'app/models/outgoing_payment.rb', line 86
validates :company_id, :supplier_id, :bank_account_id, :category, :amount, :payment_date, :currency, presence: true
|
#bank_account_id ⇒ Object
86
|
# File 'app/models/outgoing_payment.rb', line 86
validates :company_id, :supplier_id, :bank_account_id, :category, :amount, :payment_date, :currency, presence: true
|
#category ⇒ Object
86
|
# File 'app/models/outgoing_payment.rb', line 86
validates :company_id, :supplier_id, :bank_account_id, :category, :amount, :payment_date, :currency, presence: true
|
#company_id ⇒ Object
86
|
# File 'app/models/outgoing_payment.rb', line 86
validates :company_id, :supplier_id, :bank_account_id, :category, :amount, :payment_date, :currency, presence: true
|
#credit_memo_id ⇒ Object
Returns the value of attribute credit_memo_id.
111
112
113
|
# File 'app/models/outgoing_payment.rb', line 111
def credit_memo_id
@credit_memo_id
end
|
#currency ⇒ Object
86
|
# File 'app/models/outgoing_payment.rb', line 86
validates :company_id, :supplier_id, :bank_account_id, :category, :amount, :payment_date, :currency, presence: true
|
#payment_date ⇒ Object
86
|
# File 'app/models/outgoing_payment.rb', line 86
validates :company_id, :supplier_id, :bank_account_id, :category, :amount, :payment_date, :currency, presence: true
|
#supplier_id ⇒ Object
86
|
# File 'app/models/outgoing_payment.rb', line 86
validates :company_id, :supplier_id, :bank_account_id, :category, :amount, :payment_date, :currency, presence: true
|
#supplier_type ⇒ Object
Returns the value of attribute supplier_type.
111
112
113
|
# File 'app/models/outgoing_payment.rb', line 111
def supplier_type
@supplier_type
end
|
Class Method Details
.applied ⇒ ActiveRecord::Relation<OutgoingPayment>
A relation of OutgoingPayments that are applied. Active Record Scope
109
|
# File 'app/models/outgoing_payment.rb', line 109
scope :applied, -> { where(state: 'applied') }
|
.billing_address(payee, outgoing_payment_items) ⇒ Object
298
299
300
301
302
303
304
|
# File 'app/models/outgoing_payment.rb', line 298
def self.billing_address(payee, outgoing_payment_items)
billing_address = outgoing_payment_items&.first&.spiff_enrollment&.mailing_address
billing_address ||= payee&.billing_address
billing_address
end
|
.check_states_for_select ⇒ Object
210
211
212
|
# File 'app/models/outgoing_payment.rb', line 210
def self.check_states_for_select
[['No Check', :no_check], ['Queued', :queued], ['Printed', :printed], ['Reprinted', :reprinted], ['Generated', :generated]]
end
|
.get_next_reference_number ⇒ Object
359
360
361
362
|
# File 'app/models/outgoing_payment.rb', line 359
def self.get_next_reference_number
seq = OutgoingPayment.find_by_sql("SELECT nextval('payment_reference_numbers_seq') AS reference_number")
seq[0].reference_number.to_s
end
|
.payment_count(company_id = nil, bank_account_id = nil, where_conditions = nil, where_not_conditions = nil) ⇒ Object
214
215
216
217
218
219
220
221
|
# File 'app/models/outgoing_payment.rb', line 214
def self.payment_count(company_id = nil, bank_account_id = nil, where_conditions = nil, where_not_conditions = nil)
p = OutgoingPayment.order('id')
p = p.where(company_id:) unless company_id.nil?
p = p.where(bank_account_id:) unless bank_account_id.nil?
p = p.where(where_conditions) unless where_conditions.nil?
p = p.where.not(where_not_conditions) unless where_not_conditions.nil?
p.count
end
|
.print_all_checks(payment_ids, current_user) ⇒ Object
336
337
338
339
340
341
342
343
344
345
|
# File 'app/models/outgoing_payment.rb', line 336
def self.print_all_checks(payment_ids, current_user)
OutgoingPayment.transaction do
pdfs = []
payment_ids.each do |payment_id|
payment = OutgoingPayment.find(payment_id)
pdfs << payment.print_check(current_user)
end
return PdfTools.combine(pdfs, output_file_path: Upload.temp_location("combined_check_printout_#{Time.current.to_fs(:no_spaces)}.pdf"))
end
end
|
.send_checks_pending_review_notification ⇒ Object
181
182
183
184
185
186
187
188
|
# File 'app/models/outgoing_payment.rb', line 181
def self.send_checks_pending_review_notification
payments = where(category: 'check', state: 'applied', check_state: 'pending_review', review_request_sent: false)
if payments.any?
InternalMailer.checks_pending_review_notification(payments).deliver
payments.each { |payment| payment.update(review_request_sent: true) }
end
true
end
|
.send_checks_ready_to_print_notification ⇒ Object
190
191
192
193
194
195
196
197
|
# File 'app/models/outgoing_payment.rb', line 190
def self.send_checks_ready_to_print_notification
payments = where(category: 'check', state: 'applied', check_state: 'queued', print_reminder_sent: false)
if payments.any?
InternalMailer.checks_ready_to_print_notification(payments).deliver
payments.each { |payment| payment.update(print_reminder_sent: true) }
end
true
end
|
.send_daily_unprinted_checks_digest ⇒ Object
199
200
201
202
203
204
|
# File 'app/models/outgoing_payment.rb', line 199
def self.send_daily_unprinted_checks_digest
payments = applied.where(category: 'check', check_state: %w[queued generated], job_id: nil)
.includes(:company, :supplier, :outgoing_payment_items)
InternalMailer.daily_unprinted_checks_digest(payments.to_a).deliver if payments.any?
true
end
|
.states_for_select ⇒ Object
206
207
208
|
# File 'app/models/outgoing_payment.rb', line 206
def self.states_for_select
OutgoingPayment.state_machines[:state].states.map { |s| [s.human_name.titleize, s.name] }.sort
end
|
Instance Method Details
78
|
# File 'app/models/outgoing_payment.rb', line 78
belongs_to :address, foreign_key: :mailing_address_id, primary_key: :id, optional: true
|
77
|
# File 'app/models/outgoing_payment.rb', line 77
belongs_to :approved_by, class_name: 'Employee', optional: true
|
#background_job ⇒ Object
223
224
225
226
227
|
# File 'app/models/outgoing_payment.rb', line 223
def background_job
return unless job_id
BackgroundJobStatus.find(job_id)
end
|
76
|
# File 'app/models/outgoing_payment.rb', line 76
belongs_to :bank_account, optional: true
|
#build_outgoing_payment_items(voucher_items = {}, credit_memos = {}, receipts = {}) ⇒ Object
259
260
261
262
263
264
265
266
267
268
269
270
|
# File 'app/models/outgoing_payment.rb', line 259
def build_outgoing_payment_items(voucher_items = {}, credit_memos = {}, receipts = {})
outgoing_payment_items.destroy_all
voucher_items.each do |voucher_item_id, attrs|
outgoing_payment_items.build(voucher_item_id:, amount: attrs['amount_to_pay'])
end
credit_memos.each do |credit_memo_id, attrs|
outgoing_payment_items.build(credit_memo_id:, amount: attrs['amount_to_pay'])
end
receipts.each do |receipt_id, attrs|
outgoing_payment_items.build(receipt_id:, amount: attrs['amount_to_pay'])
end
end
|
#can_print_check? ⇒ Boolean
177
178
179
|
# File 'app/models/outgoing_payment.rb', line 177
def can_print_check?
category == 'check' and !voided? and !pending_review?
end
|
#checks ⇒ ActiveRecord::Relation<Check>
82
|
# File 'app/models/outgoing_payment.rb', line 82
has_many :checks
|
74
|
# File 'app/models/outgoing_payment.rb', line 74
belongs_to :company, optional: true
|
#currency_symbol ⇒ Object
249
250
251
252
253
|
# File 'app/models/outgoing_payment.rb', line 249
def currency_symbol
Money::Currency.new(currency || 'USD').symbol
rescue Money::Currency::UnknownCurrency
'$'
end
|
#editing_locked? ⇒ Boolean
245
246
247
|
# File 'app/models/outgoing_payment.rb', line 245
def editing_locked?
!draft?
end
|
#generate_check ⇒ Object
272
273
274
275
276
277
278
279
280
281
282
|
# File 'app/models/outgoing_payment.rb', line 272
def generate_check
OutgoingPayment.transaction do
outgoing_payment_items.group_by(&:payee).each do |payee, outgoing_payment_items|
check_number = bank_account.get_next_check_number
address = self.address.nil? ? OutgoingPayment.billing_address(payee, outgoing_payment_items).try(:full_address, false, ', ') : self.address.try(:full_address, false, ', ')
check = Check.create!(outgoing_payment: self, payee: payee.full_name, check_number:, bank_account:, address:, date: payment_date, amount: outgoing_payment_items.sum(&:amount))
generate_check_pdf(check)
end
trigger_check_generated
end
end
|
#generate_check_pdf(check) ⇒ Object
284
285
286
287
288
289
290
291
292
293
294
295
296
|
# File 'app/models/outgoing_payment.rb', line 284
def generate_check_pdf(check)
result = Pdf::Document::Check.new(check:, outgoing_payment: self).call
path = Upload.temp_location(check.file_name)
File.open(path, 'wb') do |file|
file.write result.pdf
file.flush
file.fsync
end
check.uploads.where(category: 'check').destroy_all
upload = Upload.uploadify(path, 'check', check, check.file_name)
check.uploads.reload
upload
end
|
#has_active_background_job? ⇒ Boolean
233
234
235
|
# File 'app/models/outgoing_payment.rb', line 233
def has_active_background_job?
background_job&.active?
end
|
#ledger_entries ⇒ ActiveRecord::Relation<LedgerEntry>
81
|
# File 'app/models/outgoing_payment.rb', line 81
has_many :ledger_entries, through: :ledger_transactions
|
#ledger_transactions ⇒ ActiveRecord::Relation<LedgerTransaction>
80
|
# File 'app/models/outgoing_payment.rb', line 80
has_many :ledger_transactions
|
#outgoing_payment_items ⇒ ActiveRecord::Relation<OutgoingPaymentItem>
79
|
# File 'app/models/outgoing_payment.rb', line 79
has_many :outgoing_payment_items, inverse_of: :outgoing_payment, dependent: :destroy
|
#payee ⇒ Object
229
230
231
|
# File 'app/models/outgoing_payment.rb', line 229
def payee
outgoing_payment_items.empty? ? nil : outgoing_payment_items.first.payee
end
|
#payment_items_applied? ⇒ Boolean
241
242
243
|
# File 'app/models/outgoing_payment.rb', line 241
def payment_items_applied?
outgoing_payment_items.sum(:amount) == amount
end
|
#print_check(current_user, regenerate_pdf: false) ⇒ Object
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
|
# File 'app/models/outgoing_payment.rb', line 306
def print_check(current_user, regenerate_pdf: false)
OutgoingPayment.transaction do
if checks.empty?
generate_check
elsif regenerate_pdf
checks.each do |check|
Rails.logger.info "Regenerating PDF for outgoing_payment id #{id}, check id #{check.id}"
generate_check_pdf(check)
end
end
printed_checks = checks.reload pdfs = printed_checks.map { |c| c.uploads.first }
check_numbers = printed_checks.collect(&:check_number)
printed_checks.each { |c| c.record_print(current_user) }
trigger_check_printed if printed_checks.any?
if pdfs.length > 1
check_temp_path = Upload.temp_location("check_#{check_numbers.join('_')}.pdf")
PdfTools.combine(pdfs, output_file_path: check_temp_path)
else
pdfs.first
end
end
end
|
#reverse(date) ⇒ Object
347
348
349
350
351
352
353
354
355
|
# File 'app/models/outgoing_payment.rb', line 347
def reverse(date)
raise 'Reversal date required' if date.nil?
OutgoingPayment.transaction do
self.reversal_date = date
self.state_event = 'void'
save!
end
end
|
#supplier ⇒ Party
75
|
# File 'app/models/outgoing_payment.rb', line 75
belongs_to :supplier, class_name: 'Party', inverse_of: :outgoing_payments, optional: true
|
#supplier_name ⇒ Object
255
256
257
|
# File 'app/models/outgoing_payment.rb', line 255
def supplier_name
supplier.try(:full_name)
end
|
#to_s ⇒ Object
173
174
175
|
# File 'app/models/outgoing_payment.rb', line 173
def to_s
"OutgoingPayment ##{reference_number}"
end
|