Created
February 27, 2020 06:55
-
-
Save ruvaleev/e6f6a26840ac6d7e239a14e76aec3a9b 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
require 'securerandom' | |
require 'fileutils' | |
## | |
# Родительский класс экспортов. | |
class BaseExport | |
attr_reader :objects, :export, :format, :file_name, :errors | |
EXPORT_DIRECTORY_NAME = 'export_files'.freeze | |
## | |
# Инициализация инстанса. | |
def initialize(objects, export, format = 'xlsx') | |
@objects = objects | |
@export = export | |
@format = format | |
@file_name = "#{export.id}_#{SecureRandom.urlsafe_base64}" | |
@errors = [] | |
end | |
## | |
# Основная логика формирования отчета. | |
def call | |
create_exports_directory | |
if @format.eql?('xlsx') | |
xls_export | |
elsif @format.eql?('csv') | |
csv_export | |
end | |
export.update(file_path: "#{EXPORT_DIRECTORY_NAME}/#{file_name}.#{format}") | |
self | |
end | |
def success? | |
errors.empty? | |
end | |
def failure? | |
!success? | |
end | |
private | |
# | |
## Создает папку экспортов, если она отсутствует. | |
def create_exports_directory | |
path = "#{Rails.public_path}/#{EXPORT_DIRECTORY_NAME}/" | |
Dir.mkdir(path) unless File.exist?(path) | |
end | |
## | |
# Путь к файлу. | |
def file_path | |
Rails.public_path.join(EXPORT_DIRECTORY_NAME, "#{file_name}.#{format}") | |
end | |
## | |
# Отчет в .xslx | |
def xls_export | |
to_xls_export.serialize(file_path) | |
end | |
## | |
# Отчет в .csv | |
def csv_export | |
to_csv_export | |
end | |
## | |
# Запись данных в xlsx файл. | |
def to_xls_export | |
Axlsx::Package.new do |xlsx_package| | |
workbook = xlsx_package.workbook | |
worksheet = workbook.add_worksheet(name: 'Export') | |
header_style = worksheet.styles.add_style(b: true, alignment: { horizontal: :center, vertical: :center }) | |
basic_style = worksheet.styles.add_style(b: false, alignment: { horizontal: :center, vertical: :center }) | |
worksheet.add_row(export_headers, style: header_style) | |
objects.each do |instance| | |
begin | |
data = export_row(instance.decorate) | |
types = Array.new(data.count, :string) | |
worksheet.add_row(data, style: basic_style, types: types) | |
rescue StandardError => e | |
errors << "#{instance.id}: #{e.to_s}" | |
end | |
end | |
end | |
end | |
## | |
# Запись данных в csv файл. | |
def to_csv_export | |
CSV.open(file_path, 'w') do |csv| | |
csv << export_headers | |
objects.each do |instance| | |
begin | |
csv << export_row(instance.decorate) | |
rescue StandardError => e | |
errors << "#{instance.id}: #{e.to_s}" | |
end | |
end | |
end | |
end | |
end |
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
## | |
# Экспорт заявок. | |
class ApplicationsManagement::Export < BaseExport | |
include ExportHelper | |
# Заголовки файла отчета. | |
def export_headers # rubocop:disable Metrics/MethodLength | |
[ | |
'ID', | |
'Status', | |
'Borrower', | |
'Loan sum', | |
'Approved loan sum', | |
'Requested loan sum', | |
'Loan term', | |
'Gender', | |
'Date of bir', | |
'Mobile phone', | |
'Document number', | |
'Email', | |
'Loan type', | |
'Check status', | |
'Reason', | |
'Verificator name', | |
'Verification mobile phone status', | |
'Verification mobile phone reason', | |
'Verification work phone status', | |
'Verification work phone reason', | |
'Verification guarantor phone status', | |
'Verification guarantor phone reason', | |
'PV comments', | |
'Mobile phone call comments', | |
'Work phone call comments', | |
'Contact person phone call comments', | |
'TS name', | |
'TS comments', | |
'Living postal code', | |
'Living province', | |
'Living city', | |
'Living district', | |
'Living street', | |
'Living house number', | |
'Living apartment number', | |
'Living home phone', | |
'Work place', | |
'Work guarantor full name', | |
'Work position', | |
'Work address', | |
'Work phone', | |
'Work industry', | |
'Social status', | |
'Monly income', | |
'Bank name', | |
'Bank account holder', | |
'Bank account number', | |
'Bank branch name', | |
'Bank branch code', | |
'Bank code', | |
'IP', | |
'Browser', | |
'Number of children', | |
'Guarantor', | |
'UUID', | |
'Have contract', | |
'repeat sale', | |
'Number of revisions monly income field', | |
'Number of revisions document number field', | |
'Number of revisions mobile phone field', | |
'Number of revisions work phone field', | |
'Created at', | |
'Updated at', | |
'Action date', | |
'Staff id', | |
'Next at', | |
'Start at', | |
'End at', | |
'Iamreal vfv result', | |
'Iamreal vfv reason', | |
'Iamreal fb score', | |
'Iamreal fb significance', | |
'Iamreal processed at', | |
'Approval kind', | |
'KYC' | |
] | |
end | |
## | |
# Записываемые данные по каждой заявке. | |
def export_row(application) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize | |
[ | |
application.id, | |
application.status, | |
application.display_full_name, | |
application.display_amount, | |
application.display_approved_loan_sum, | |
application.display_requested_loan_sum, | |
application.display_term_raw, | |
application.display_gender, | |
application.display_date_of_birth, | |
application.mobile_phone, | |
application.document_number, | |
application.email, | |
application.loan_type, | |
application.check&.status, | |
application.check&.stop_factors && application&.check&.stop_factors&.map(&:humanize)&.join(', '), | |
application.display_verificator_name, | |
application.phones_verification&.calls&.find { |x| x.type.eql?('mobile_phone') }&.status || 'N/A', | |
application.phones_verification&.calls&.find { |x| x.type.eql?('mobile_phone') }&.result&.title || 'N/A', | |
application.phones_verification&.calls&.find { |x| x.type.eql?('work_phone') }&.status || 'N/A', | |
application.phones_verification&.calls&.find { |x| x.type.eql?('work_phone') }&.result&.title || 'N/A', | |
application.phones_verification&.calls&.find { |x| x.type.eql?('guarantor_mobile_phone') }&.status || 'N/A', | |
application.phones_verification&.calls&.find { |x| x.type.eql?('guarantor_mobile_phone') }&.result&.title || 'N/A', | |
application.comments.map { |c| "#{c.text} (#{c.author.full_name})" }.join(' / '), | |
application.phones_verification&.calls&.find { |x| x.type.eql?('mobile_phone') }&.comments&.join(' / ') || 'N/A', | |
application.phones_verification&.calls&.find { |x| x.type.eql?('work_phone') }&.comments&.join(' / ') || 'N/A', | |
application.phones_verification&.calls&.find { |x| x.type.eql?('guarantor_mobile_phone') }&.comments&.join(' / ') || 'N/A', | |
application.telesales_staff_name, | |
application.telesales_comments, | |
application.living_postal_code, | |
application.living_province&.title, | |
application.living_city&.title, | |
application.living_district&.title, | |
application.living_street, | |
application.living_house_number, | |
application.living_apartment_number, | |
application.living_home_phone, | |
application.work_place, | |
application.work_guarantor_full_name, | |
application.work_position, | |
application.work_address, | |
application.work_phone, | |
application.display_working_industry, | |
application&.occupation&.translations&.select { |x| x.locale.eql?('en') }&.first&.value || '', | |
application.display_monthly_income, | |
application.bank_name, | |
application.bank_account_holder, | |
application.bank_account_number, | |
application.bank_branch_name, | |
application.bank_branch_code, | |
application.bank_code, | |
application.ip, | |
application.browser, | |
application.number_of_children, | |
application.guarantor.full_name, | |
application.uuid, | |
application.have_contract, | |
application.repeat_sale, | |
application.number_of_revisions_monthly_income_field, | |
application.number_of_revisions_document_number_field, | |
application.number_of_revisions_mobile_phone_field, | |
application.number_of_revisions_work_phone_field, | |
application.created_at, | |
application.updated_at, | |
application.action_date, | |
application.staff_id, | |
application.next_at, | |
application.start_at, | |
application.end_at, | |
application.iamreal_vfv_result, | |
application.iamreal_vfv_reason, | |
application.iamreal_fb_score, | |
application.iamreal_fb_significance, | |
application.iamreal_processed_at, | |
display_approval_kind(application.approval_kind), | |
application.photo_urls.present? ? 'Yes' : 'No' | |
] | |
end | |
end |
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
## | |
# Экспорт заявок. | |
class ApplicationsManagement::NewExport < BaseExport | |
attr_reader :objects_ids, :export_id, :format, :file_name, :errors | |
include ExportHelper | |
# Инициализация инстанса. | |
def initialize(objects_ids, export_id, format = 'xlsx') | |
@objects_ids = objects_ids | |
@export_id = export_id | |
@format = format | |
@file_name = "#{export_id}_#{SecureRandom.urlsafe_base64}" | |
@errors = [] | |
end | |
## | |
# Основная логика формирования отчета. | |
def call | |
create_exports_directory | |
if @format.eql?('xlsx') | |
xls_export | |
elsif @format.eql?('csv') | |
csv_export | |
end | |
Export.find(export_id).update(file_path: "#{EXPORT_DIRECTORY_NAME}/#{file_name}.#{format}") | |
self | |
end | |
def success? | |
errors.empty? | |
end | |
def failure? | |
!success? | |
end | |
private | |
# | |
## Создает папку экспортов, если она отсутствует. | |
def create_exports_directory | |
path = "#{Rails.public_path}/#{EXPORT_DIRECTORY_NAME}/" | |
Dir.mkdir(path) unless File.exist?(path) | |
end | |
## | |
# Отчет в .xslx | |
def xls_export | |
to_xls_export.serialize(file_path) | |
end | |
## | |
# Отчет в .csv | |
def csv_export | |
to_csv_export | |
end | |
## | |
# Запись данных в xlsx файл. | |
def to_xls_export | |
Axlsx::Package.new do |xlsx_package| | |
workbook = xlsx_package.workbook | |
worksheet = workbook.add_worksheet(name: 'Export') | |
header_style = worksheet.styles.add_style(b: true, alignment: { horizontal: :center, vertical: :center }) | |
basic_style = worksheet.styles.add_style(b: false, alignment: { horizontal: :center, vertical: :center }) | |
worksheet.add_row(export_headers, style: header_style) | |
objects_ids.each do |application_id| | |
begin | |
write_row(application_id, worksheet, basic_style) | |
rescue StandardError => e | |
errors << "#{application_id}: #{e.to_s}" | |
end | |
end | |
end | |
end | |
def write_row(application_id, worksheet, basic_style) | |
application = Application.find(application_id) | |
data = export_row(application.decorate) | |
types = Array.new(data.size, :string) | |
worksheet.add_row(data, style: basic_style, types: types) | |
end | |
## | |
# Путь к файлу. | |
def file_path | |
Rails.public_path.join(EXPORT_DIRECTORY_NAME, "#{file_name}.#{format}") | |
end | |
## | |
# Запись данных в csv файл. | |
def to_csv_export | |
CSV.open(file_path, 'w') do |csv| | |
csv << export_headers | |
objects.each do |instance| | |
begin | |
csv << export_row(instance.decorate) | |
rescue StandardError => e | |
errors << "#{instance.id}: #{e.to_s}" | |
end | |
end | |
end | |
end | |
# Заголовки файла отчета. | |
def export_headers # rubocop:disable Metrics/MethodLength | |
[ | |
'ID', | |
'Status', | |
'Borrower', | |
'Loan sum', | |
'Approved loan sum', | |
'Requested loan sum', | |
'Loan term', | |
'Gender', | |
'Date of bir', | |
'Mobile phone', | |
'Document number', | |
'Email', | |
'Loan type', | |
'Check status', | |
'Reason', | |
'Verificator name', | |
'Verification mobile phone status', | |
'Verification mobile phone reason', | |
'Verification work phone status', | |
'Verification work phone reason', | |
'Verification guarantor phone status', | |
'Verification guarantor phone reason', | |
'PV comments', | |
'Mobile phone call comments', | |
'Work phone call comments', | |
'Contact person phone call comments', | |
'TS name', | |
'TS comments', | |
'Living postal code', | |
'Living province', | |
'Living city', | |
'Living district', | |
'Living street', | |
'Living house number', | |
'Living apartment number', | |
'Living home phone', | |
'Work place', | |
'Work guarantor full name', | |
'Work position', | |
'Work address', | |
'Work phone', | |
'Work industry', | |
'Social status', | |
'Monly income', | |
'Bank name', | |
'Bank account holder', | |
'Bank account number', | |
'Bank branch name', | |
'Bank branch code', | |
'Bank code', | |
'IP', | |
'Browser', | |
'Number of children', | |
'Guarantor', | |
'UUID', | |
'Have contract', | |
'repeat sale', | |
'Number of revisions monly income field', | |
'Number of revisions document number field', | |
'Number of revisions mobile phone field', | |
'Number of revisions work phone field', | |
'Created at', | |
'Updated at', | |
'Action date', | |
'Staff id', | |
'Next at', | |
'Start at', | |
'End at', | |
'Iamreal vfv result', | |
'Iamreal vfv reason', | |
'Iamreal fb score', | |
'Iamreal fb significance', | |
'Iamreal processed at', | |
'Approval kind', | |
'KYC' | |
] | |
end | |
## | |
# Записываемые данные по каждой заявке. | |
def export_row(application) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize | |
[ | |
application.id, | |
application.status, | |
application.display_full_name, | |
application.display_amount, | |
application.display_approved_loan_sum, | |
application.display_requested_loan_sum, | |
application.display_term_raw, | |
application.display_gender, | |
application.display_date_of_birth, | |
application.mobile_phone, | |
application.document_number, | |
application.email, | |
application.loan_type, | |
application.check&.status, | |
application.check&.stop_factors && application&.check&.stop_factors&.map(&:humanize)&.join(', '), | |
application.display_verificator_name, | |
application.phones_verification&.calls&.find { |x| x.type.eql?('mobile_phone') }&.status || 'N/A', | |
application.phones_verification&.calls&.find { |x| x.type.eql?('mobile_phone') }&.result&.title || 'N/A', | |
application.phones_verification&.calls&.find { |x| x.type.eql?('work_phone') }&.status || 'N/A', | |
application.phones_verification&.calls&.find { |x| x.type.eql?('work_phone') }&.result&.title || 'N/A', | |
application.phones_verification&.calls&.find { |x| x.type.eql?('guarantor_mobile_phone') }&.status || 'N/A', | |
application.phones_verification&.calls&.find { |x| x.type.eql?('guarantor_mobile_phone') }&.result&.title || 'N/A', | |
application.comments.map { |c| "#{c.text} (#{c.author.full_name})" }.join(' / '), | |
application.phones_verification&.calls&.find { |x| x.type.eql?('mobile_phone') }&.comments&.join(' / ') || 'N/A', | |
application.phones_verification&.calls&.find { |x| x.type.eql?('work_phone') }&.comments&.join(' / ') || 'N/A', | |
application.phones_verification&.calls&.find { |x| x.type.eql?('guarantor_mobile_phone') }&.comments&.join(' / ') || 'N/A', | |
application.telesales_staff_name, | |
application.telesales_comments, | |
application.living_postal_code, | |
application.living_province&.title, | |
application.living_city&.title, | |
application.living_district&.title, | |
application.living_street, | |
application.living_house_number, | |
application.living_apartment_number, | |
application.living_home_phone, | |
application.work_place, | |
application.work_guarantor_full_name, | |
application.work_position, | |
application.work_address, | |
application.work_phone, | |
application.display_working_industry, | |
application&.occupation&.translations&.select { |x| x.locale.eql?('en') }&.first&.value || '', | |
application.display_monthly_income, | |
application.bank_name, | |
application.bank_account_holder, | |
application.bank_account_number, | |
application.bank_branch_name, | |
application.bank_branch_code, | |
application.bank_code, | |
application.ip, | |
application.browser, | |
application.number_of_children, | |
application.guarantor.full_name, | |
application.uuid, | |
application.have_contract, | |
application.repeat_sale, | |
application.number_of_revisions_monthly_income_field, | |
application.number_of_revisions_document_number_field, | |
application.number_of_revisions_mobile_phone_field, | |
application.number_of_revisions_work_phone_field, | |
application.created_at, | |
application.updated_at, | |
application.action_date, | |
application.staff_id, | |
application.next_at, | |
application.start_at, | |
application.end_at, | |
application.iamreal_vfv_result, | |
application.iamreal_vfv_reason, | |
application.iamreal_fb_score, | |
application.iamreal_fb_significance, | |
application.iamreal_processed_at, | |
display_approval_kind(application.approval_kind), | |
application.photo_urls.present? ? 'Yes' : 'No' | |
] | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment