88 lines
3.0 KiB
Ruby
88 lines
3.0 KiB
Ruby
require 'zip'
|
|
require 'stringio'
|
|
|
|
|
|
class FileProcessorJob
|
|
include Sidekiq::Job
|
|
|
|
def perform(inn, report_id)
|
|
report = Report.find(report_id)
|
|
Rails.logger.info "=== Начало загрузки для ИНН: #{inn} ==="
|
|
|
|
# Временная папка
|
|
temp_dir = Rails.root.join('tmp', 'reports', inn)
|
|
FileUtils.mkdir_p(temp_dir)
|
|
|
|
download_inn(inn, temp_dir.to_s)
|
|
|
|
# Найти или создать организацию по ИНН
|
|
organization = Organization.find_or_create_by!(inn: inn)
|
|
|
|
Dir.glob("#{temp_dir}/**/*").select { |f| File.file?(f) }.each do |file_path|
|
|
# Прикрепляем файл к Report (обратная совместимость)
|
|
report.files.attach(
|
|
io: File.open(file_path),
|
|
filename: File.basename(file_path)
|
|
)
|
|
|
|
# Создаём YearlyFile и прикрепляем xlsx
|
|
yearly_file = organization.yearly_files.build(year: 0)
|
|
yearly_file.file.attach(
|
|
io: File.open(file_path),
|
|
filename: File.basename(file_path)
|
|
)
|
|
yearly_file.save!
|
|
|
|
# Парсим данные из xlsx
|
|
ReportParser.new(yearly_file).call
|
|
end
|
|
|
|
# Удали временные файлы
|
|
FileUtils.rm_rf(temp_dir)
|
|
|
|
report.update!(status: 'completed')
|
|
Rails.logger.info "=== Завершено для ИНН: #{inn} ==="
|
|
rescue => e
|
|
report.update!(status: 'failed') if report
|
|
Rails.logger.error "=== ОШИБКА: #{e.message} ==="
|
|
raise
|
|
end
|
|
|
|
|
|
private
|
|
|
|
def get_content(url, json_need = false)
|
|
headers = {
|
|
'User-Agent' => "Mozilla/5.0 (Windows NT 10.0; Win64; x64)",
|
|
'Accept-Language' => 'en-US,en;q=0.9',
|
|
'Accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8'
|
|
}
|
|
content = HTTParty.get(url, headers: headers).body
|
|
json_need ? JSON.parse(content) : content
|
|
end
|
|
|
|
def download_inn(inn, output)
|
|
url = "https://bo.nalog.gov.ru/advanced-search/organizations/search?query=#{inn}&page=0&size=20"
|
|
content = get_content(url, true)
|
|
id = content['content'][0]['id']
|
|
|
|
url = "https://bo.nalog.gov.ru/nbo/organizations/#{id}/bfo/"
|
|
content = get_content(url, true)
|
|
periods_and_details_ids = content.map { |item| [item['period'], item['typeCorrections'][0]['correction']['id']] }
|
|
|
|
periods_and_details_ids.each do |period, details_id|
|
|
url = "https://bo.nalog.gov.ru/download/bfo/#{id}?auditReport=false&balance=true"\
|
|
"&capitalChange=true&clarification=false&targetedFundsUsing=false&detailsId=#{details_id}"\
|
|
"&financialResult=true&fundsMovement=true&type=XLS&period=#{period}"
|
|
content = get_content(url)
|
|
|
|
zip_file = Zip::File.open_buffer(StringIO.new(content))
|
|
zip_file.each do |entry|
|
|
output_file = File.join(output, entry.name)
|
|
FileUtils.mkdir_p(File.dirname(output_file))
|
|
zip_file.extract(entry, output_file) { true } # перезаписывать если существует
|
|
end
|
|
end
|
|
end
|
|
end
|