Created
December 23, 2019 18:59
-
-
Save cored/c0efcbea457ce503e2d1447f65fa8b5a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# frozen_string_literal: true | |
module Billing | |
module Models | |
class InvoiceItem < ActiveRecord::Base | |
extend Memoist | |
include Mixins::Reportable | |
include Phobos::Checkr::Producer | |
validates_uniqueness_of :report_id, scope: :invoice_id | |
belongs_to :invoice | |
delegate :start_date, :end_date, to: :invoice | |
attribute :program_name, :string | |
FEE_TYPES = %i[ | |
county_fees | |
county_service_fees | |
dmv_fees | |
service_fees | |
state_fees | |
state_service_fees | |
education_fees | |
employment_service_fees | |
international_education_service_fees | |
international_employment_service_fees | |
motor_vehicle_report_service_fees | |
drug_screening_surcharges | |
health_screening_surcharges | |
pointer_criminal_state_fees | |
pointer_state_criminal_service_fees | |
municipal_court_fees | |
municipal_service_fees | |
].freeze | |
FEE_TYPES.each do |fee_type| | |
scope "zero_#{fee_type}".to_sym, -> { where(fee_type => 0) } | |
scope "non_zero_#{fee_type}".to_sym, -> { where.not(fee_type => 0) } | |
end | |
scope :zero_fees, lambda { | |
FEE_TYPES[1..-1].inject(send("zero_#{FEE_TYPES[0]}")) do |chain, fee_type| | |
chain.send("zero_#{fee_type}") | |
end | |
} | |
scope :non_zero_fees, lambda { | |
FEE_TYPES[1..-1].inject(send("non_zero_#{FEE_TYPES[0]}")) do |chain, fee_type| | |
chain.send(:or, send("non_zero_#{fee_type}")) | |
end | |
} | |
def self.invoice!(account_id:, year:, month:, report_id:) | |
publish( | |
topic: Handlers::InvoiceItemHandler::TOPIC_NAME, | |
payload: { | |
account_id: account_id, | |
month: month, | |
year: year, | |
report_id: report_id | |
}.to_json, | |
partition_key: "#{account_id}-#{year}-#{month}-#{report_id}" | |
) | |
end | |
def events | |
@events ||= Event.where( | |
invoice_date: start_date..end_date, | |
report_id: report_id | |
).to_a.uniq(&:signature).sort_by { |e| -e.context_date.to_i } | |
end | |
def package_setting | |
invoice.find_package(report.package_id) | |
end | |
memoize :package_setting | |
def applicant_pay? | |
!!package_setting&.try(:[], :applicant_pay?) | |
end | |
def price_events! | |
events.reverse_each do |event| | |
event.amount = Pricing.price_event(event, invoice) | |
event.save(validate: false) | |
end | |
end | |
def summarize! | |
item_summary = Summary.new(events) | |
self.summary = item_summary.counts | |
FEE_TYPES.each do |fee_type| | |
send("#{fee_type}=", item_summary.totals[fee_type]) | |
end | |
self.total_amount = item_summary.totals[:all] | |
end | |
def aggregate_summary | |
summary.reject do |category, _labels| | |
skippable_category?(category) | |
end | |
end | |
def skippable_category?(category) | |
%w[events reports].include? category | |
end | |
def fill_extra_fields! | |
fill_candidate! | |
fill_report! | |
self.csv = generate_csv | |
end | |
def fill_candidate! | |
return unless candidate | |
self.candidate_custom_id = candidate.custom_id | |
self.candidate_name = candidate.name | |
self.candidate_geo_id = candidate.geo_id | |
self.candidate_geo_name = candidate.geo_name | |
end | |
def fill_report! | |
self.alias_count = calculate_alias_count | |
self.program_name = package_setting&.try(:[], :program_name) | |
self.package_title = retrieve_package_title | |
self.cost_center = retrieve_cost_center | |
self.segment_stamps = retrieve_segment_stamps | |
self.report_completed_at = completed_at | |
self.report_created_at = created_at | |
self.report_upgraded_at = upgraded_at | |
self.report_revised_at = revised_at | |
self.report_account_name = account_name | |
end | |
def generate_csv | |
Billing::Invoices::CSV::HEADERS.keys.map do |attribute| | |
value = case attribute | |
when :state_fees then pointer_and_state_fees | |
when :state_service_fees then pointer_and_state_service_fees | |
else public_send(attribute) | |
end | |
attribute_value_to_csv(attribute, value)&.to_s | |
end | |
end | |
def pointer_and_state_fees | |
[ | |
public_send(:state_fees), | |
public_send(:pointer_criminal_state_fees) | |
].compact.sum | |
end | |
def pointer_and_state_service_fees | |
[ | |
public_send(:state_service_fees), | |
public_send(:pointer_state_criminal_service_fees) | |
].compact.sum | |
end | |
def attribute_value_to_csv(attribute, value) | |
return value if attribute == :alias_count | |
return value / 100.0 if value.to_f == value | |
return nil if value.nil? | |
return "\"#{value}\"" if attribute == :candidate_custom_id | |
value | |
end | |
def account_name | |
subaccounts = invoice.account_settings.fetch('subaccounts', {}) | |
account = subaccounts[final_event.account_id] unless subaccounts.empty? | |
account ||= invoice.account_settings | |
account.fetch('name') | |
end | |
def report | |
@report ||= Report.find(report_id) | |
end | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment