Skip to content

Commit

Permalink
New type of data export just for quarters
Browse files Browse the repository at this point in the history
Now it's required to recover the original numeric answer data export and
bump the new funcionality into a new data export type
  • Loading branch information
Novruu committed Oct 17, 2024
1 parent 041a5a1 commit 50c48e5
Show file tree
Hide file tree
Showing 5 changed files with 148 additions and 142 deletions.
5 changes: 3 additions & 2 deletions app/models/data_export.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ class DataExport < ApplicationRecord
DATA_EXPORT_TYPES = {
"standard_loan_data_export" => "StandardLoanDataExport",
"enhanced_loan_data_export" => "EnhancedLoanDataExport",
"numeric_answer_data_export" => "NumericAnswerDataExport"
"numeric_answer_data_export" => "NumericAnswerDataExport",
"numeric_with_account_history_data_export" => "NumericAnswerWithAccountHistoryDataExport"
}

def self.model_name
Expand All @@ -23,7 +24,7 @@ def self.model_name
def process_data
@child_errors = []
data = []
quarters = type == "NumericAnswerDataExport" ? quarters_between(start_date, end_date) : nil
quarters = type == "NumericAnswerWithAccountHistoryDataExport" ? quarters_between(start_date, end_date) : nil
data.concat(header_rows(quarters))
scope.find_each do |object|
begin
Expand Down
141 changes: 1 addition & 140 deletions app/models/numeric_answer_data_export.rb
Original file line number Diff line number Diff line change
@@ -1,148 +1,9 @@
class NumericAnswerDataExport < EnhancedLoanDataExport

QUARTERLY_KEYS = [
:sum_of_disbursements, :sum_of_repayments, :repayments_of_principal,
:repayments_of_interest, :final_principal_balance, :final_interest_balance
]

def q_data_types
["number", "percentage", "rating", "currency", "range"]
end

def include_numeric_answer_in_export?(str)
true if Float(str) rescue false
end

protected

def object_data_as_hash(loan, quarters)

hash = {
loan_id: loan.id,
name: loan.name,
division: loan.division_name,
division_membership_status: loan.division_membership_status,
cooperative: loan.coop_name,
address: loan.coop_street_address,
city: loan.coop_city,
state: loan.coop_state,
country: loan.coop_country&.name,
postal_code: loan.coop_postal_code,
entity_structure: loan.coop_entity_structure,
naics_code: loan.coop_naics_code,
census_tract_code: loan.coop_census_tract_code,
date_established: loan.coop_date_established,
status: loan.status.to_s,
actual_end_date: loan.actual_end_date,
actual_first_payment_date: loan.actual_first_payment_date,
projected_end_date: loan.projected_end_date,
projected_first_payment_date: loan.projected_first_payment_date,
signing_date: loan.signing_date,
length_months: loan.length_months,
loan_type: loan.loan_type.to_s,
currency: loan.currency&.name,
amount: loan.amount,
rate: loan.rate,
source_of_capital: loan.source_of_capital,
final_repayment_formula: loan.final_repayment_formula,
primary_agent: loan.primary_agent&.name,
secondary_agent: loan.secondary_agent&.name,
num_accounting_warnings: loan.num_sync_issues_by_level(:warning),
num_accounting_errors: loan.num_sync_issues_by_level(:error),
accrued_interest: loan.total_accrued_interest(start_date: start_date, end_date: end_date),
change_in_principal: loan.change_in_principal(start_date: start_date, end_date: end_date),
change_in_interest: loan.change_in_interest(start_date: start_date, end_date: end_date)
}

hash.transform_keys! { |k| I18n.t("standard_loan_data_exports.headers.#{k}") }

for key in QUARTERLY_KEYS do
total = 0
for quarter in quarters do
result = loan.send(key, start_date: quarter[0], end_date: quarter[1])
hash["#{I18n.t("standard_loan_data_exports.headers.#{key}")} #{quarter[2]}"] = result
total += result || 0
end
hash["#{I18n.t("standard_loan_data_exports.headers.#{key}")}"] = total > 0 ? total : nil
end

hash["#{I18n.t("standard_loan_data_exports.headers.#{:created_at}")}"] = loan.created_at.to_date
hash["#{I18n.t("standard_loan_data_exports.headers.#{:updated_at}")}"] = loan.updated_at.to_date

return hash.merge(response_hash(loan))
end

def header_rows(quarters)
[main_header_row(quarters), question_id_row]
end

def main_header_row(quarters)
headers = StandardLoanDataExport::HEADERS - QUARTERLY_KEYS
updated_at = I18n.t("standard_loan_data_exports.headers.#{headers.pop}")
created_at = I18n.t("standard_loan_data_exports.headers.#{headers.pop}")
headers.map! { |h| I18n.t("standard_loan_data_exports.headers.#{h}") }

for key in QUARTERLY_KEYS do
for quarter in quarters do
headers.push("#{I18n.t("standard_loan_data_exports.headers.#{key}")} #{quarter[2]}")
end
headers.push("#{I18n.t("standard_loan_data_exports.headers.#{key}")}")
end

headers.push(created_at)
headers.push(updated_at)

@main_headers = headers
@total_headers = headers + questions.map { |q| q.label.to_s }
@quarters = quarters

return @total_headers
end

def question_id_row
row = [I18n.t("standard_loan_data_exports.headers.question_id")]
row[@main_headers.size - 1] = nil
row + questions.map(&:id)
end

def header_symbols
@header_symbols ||= @main_headers + questions.map(&:id)
end

private

def get_quarter(date)
remaining = (date.month - (3 * (date.month / 3.0).ceil)).abs
end_month = date.month + remaining
end_day = Date.civil(date.year, end_month, -1).day

return [
"#{date.year}/#{date.month}/#{date.day}",
"#{date.year}/#{end_month}/#{end_day}",
"Q#{(end_month / 3.0).ceil}#{date.year}",
Date.civil(end_month >= 12 ? date.year + 1 : date.year, end_month >= 12 ? 1 : end_month + 1, 1)
]
end

def quarters_between(date_a, date_b)
if (date_a >= date_b)
Rails.logger.error("Invalid dates")
return
end

quarters = []
next_quarter = date_a

loop do
quarter_start, quarter_end, quarter_name, next_quarter = get_quarter(next_quarter)
quarters = quarters.append([ quarter_start, quarter_end, quarter_name ])

if next_quarter > date_b
break
end
end

quarters[-1][1] = "#{date_b.year}/#{date_b.month}/#{date_b.day}"
return quarters
end
end
end
140 changes: 140 additions & 0 deletions app/models/numeric_answer_with_account_history_data_export.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
class NumericAnswerWithAccountHistoryDataExport < NumericAnswerDataExport

QUARTERLY_KEYS = [
:sum_of_disbursements, :sum_of_repayments, :repayments_of_principal,
:repayments_of_interest, :final_principal_balance, :final_interest_balance
]

protected

def object_data_as_hash(loan, quarters)

hash = {
loan_id: loan.id,
name: loan.name,
division: loan.division_name,
division_membership_status: loan.division_membership_status,
cooperative: loan.coop_name,
address: loan.coop_street_address,
city: loan.coop_city,
state: loan.coop_state,
country: loan.coop_country&.name,
postal_code: loan.coop_postal_code,
entity_structure: loan.coop_entity_structure,
naics_code: loan.coop_naics_code,
census_tract_code: loan.coop_census_tract_code,
date_established: loan.coop_date_established,
status: loan.status.to_s,
actual_end_date: loan.actual_end_date,
actual_first_payment_date: loan.actual_first_payment_date,
projected_end_date: loan.projected_end_date,
projected_first_payment_date: loan.projected_first_payment_date,
signing_date: loan.signing_date,
length_months: loan.length_months,
loan_type: loan.loan_type.to_s,
currency: loan.currency&.name,
amount: loan.amount,
rate: loan.rate,
source_of_capital: loan.source_of_capital,
final_repayment_formula: loan.final_repayment_formula,
primary_agent: loan.primary_agent&.name,
secondary_agent: loan.secondary_agent&.name,
num_accounting_warnings: loan.num_sync_issues_by_level(:warning),
num_accounting_errors: loan.num_sync_issues_by_level(:error),
accrued_interest: loan.total_accrued_interest(start_date: start_date, end_date: end_date),
change_in_principal: loan.change_in_principal(start_date: start_date, end_date: end_date),
change_in_interest: loan.change_in_interest(start_date: start_date, end_date: end_date)
}

hash.transform_keys! { |k| I18n.t("standard_loan_data_exports.headers.#{k}") }

for key in QUARTERLY_KEYS do
total = 0
for quarter in quarters do
result = loan.send(key, start_date: quarter[0], end_date: quarter[1])
hash["#{I18n.t("standard_loan_data_exports.headers.#{key}")} #{quarter[2]}"] = result
total += result || 0
end
hash["#{I18n.t("standard_loan_data_exports.headers.#{key}")}"] = total > 0 ? total : nil
end

hash["#{I18n.t("standard_loan_data_exports.headers.#{:created_at}")}"] = loan.created_at.to_date
hash["#{I18n.t("standard_loan_data_exports.headers.#{:updated_at}")}"] = loan.updated_at.to_date

return hash.merge(response_hash(loan))
end

def header_rows(quarters)
[main_header_row(quarters), question_id_row]
end

def main_header_row(quarters)
headers = StandardLoanDataExport::HEADERS - QUARTERLY_KEYS
updated_at = I18n.t("standard_loan_data_exports.headers.#{headers.pop}")
created_at = I18n.t("standard_loan_data_exports.headers.#{headers.pop}")
headers.map! { |h| I18n.t("standard_loan_data_exports.headers.#{h}") }

for key in QUARTERLY_KEYS do
for quarter in quarters do
headers.push("#{I18n.t("standard_loan_data_exports.headers.#{key}")} #{quarter[2]}")
end
headers.push("#{I18n.t("standard_loan_data_exports.headers.#{key}")}")
end

headers.push(created_at)
headers.push(updated_at)

@main_headers = headers
@total_headers = headers + questions.map { |q| q.label.to_s }
@quarters = quarters

return @total_headers
end

def question_id_row
row = [I18n.t("standard_loan_data_exports.headers.question_id")]
row[@main_headers.size - 1] = nil
row + questions.map(&:id)
end

def header_symbols
@header_symbols ||= @main_headers + questions.map(&:id)
end

private

def get_quarter(date)
remaining = (date.month - (3 * (date.month / 3.0).ceil)).abs
end_month = date.month + remaining
end_day = Date.civil(date.year, end_month, -1).day

return [
"#{date.year}/#{date.month}/#{date.day}",
"#{date.year}/#{end_month}/#{end_day}",
"Q#{(end_month / 3.0).ceil}#{date.year}",
Date.civil(end_month >= 12 ? date.year + 1 : date.year, end_month >= 12 ? 1 : end_month + 1, 1)
]
end

def quarters_between(date_a, date_b)
if (date_a >= date_b)
Rails.logger.error("Invalid dates")
return
end

quarters = []
next_quarter = date_a

loop do
quarter_start, quarter_end, quarter_name, next_quarter = get_quarter(next_quarter)
quarters = quarters.append([ quarter_start, quarter_end, quarter_name ])

if next_quarter > date_b
break
end
end

quarters[-1][1] = "#{date_b.year}/#{date_b.month}/#{date_b.day}"
return quarters
end
end
2 changes: 2 additions & 0 deletions app/views/admin/data_exports/choose_type.html.slim
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@ p
= link_to t("data_exports.types.enhanced_loan_data_export"), new_admin_data_export_path("enhanced_loan_data_export")
p
= link_to t("data_exports.types.numeric_answer_data_export"), new_admin_data_export_path("numeric_answer_data_export")
p
= link_to t("data_exports.types.numeric_with_account_history_data_export"), new_admin_data_export_path("numeric_with_account_history_data_export")
2 changes: 2 additions & 0 deletions config/locales/en/data_exports.en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,13 @@ en:
standard_loan_data_export: "New Standard Loan Data Export"
enhanced_loan_data_export: "Enhanced Loan Data Export"
numeric_answer_data_export: "Numeric Answer Only Loan Data Export"
numeric_with_account_history_data_export: "Numeric Answer With Accounting History (beta)"
types:
data_export: "Data Export"
standard_loan_data_export: "Standard Loan Data Export"
enhanced_loan_data_export: "Enhanced Loan Data Export"
numeric_answer_data_export: "Numeric Answer Only Loan Data Export"
numeric_with_account_history_data_export: "Numeric Answer With Accounting History (beta)"
standard_loan_data_exports:
headers:
accrued_interest: "Accrued Interest"
Expand Down

0 comments on commit 50c48e5

Please sign in to comment.