Контроллер настроен на парсер, готово к PR

This commit is contained in:
Dmitry
2026-03-12 13:26:48 +03:00
parent c016d6a319
commit f973ec78df
6 changed files with 142 additions and 42 deletions
+9 -13
View File
@@ -1,17 +1,13 @@
class AuditorsController < ApplicationController
def index
@info_about_auditors = {"A" => {"Наименование аудиторской организации/ФИО индивидуального аудитора" => "ООО \"Инвест-Аудит\"",
"ИНН" => 7606073440,
"ОГРН/ОРГНИП" => 1097606001250
},
"B" => {"Наименование аудиторской организации/ФИО индивидуального аудитора" => "ООО \"Инвест-Аудит\"",
"ИНН" => 7606073440,
"ОГРН/ОРГНИП" => 1097606001250
},
"C" => {"Наименование аудиторской организации/ФИО индивидуального аудитора" => "ООО \"Инвест-Аудит\"",
"ИНН" => 7606073440,
"ОГРН/ОРГНИП" => 1097606001250
}
}
auditors = Auditor.all
@info_about_auditors = auditors.each_with_object({}) do |auditor, hash|
hash[auditor.id] = {
"Наименование аудиторской организации/ФИО индивидуального аудитора" => auditor.name,
"ИНН" => auditor.inn,
"ОГРН/ОРГНИП" => auditor.ogrn
}
end
end
end
+14 -28
View File
@@ -1,33 +1,19 @@
class WelcomeController < ApplicationController
def index
@info_about_organisations = {"A" => {"ИНН" => 7707602010,
"Полное наименование юридического лица" =>"Публичное акционерное общество \"М.видео\"",
"КПП" => 770101001,
"Код по ОКПО" => 71630621,
"Форма собственности (по ОКФС)" => "34 Совместная частная и иностранная собственность",
"Организационно-правовая форма (по ОКОПФ)" => "12247 Публичные акционерные общества",
"Вид экономической деятельности по ОКВЭД 2" => "70.10.1",
"Местонахождение (адрес)" => "105066, г. Москва, ул. Красносельская Нижн., д. 40/12, к. 20, пом. II"
},
"B" => {"ИНН" => 7707602010,
"Полное наименование юридического лица" =>"Публичное акционерное общество \"М.видео\"",
"КПП" => 770101001,
"Код по ОКПО" => 71630621,
"Форма собственности (по ОКФС)" => "34 Совместная частная и иностранная собственность",
"Организационно-правовая форма (по ОКОПФ)" => "12247 Публичные акционерные общества",
"Вид экономической деятельности по ОКВЭД 2" => "70.10.1",
"Местонахождение (адрес)" => "105066, г. Москва, ул. Красносельская Нижн., д. 40/12, к. 20, пом. II"
},
"C" => {"ИНН" => 7707602010,
"Полное наименование юридического лица" =>"Публичное акционерное общество \"М.видео\"",
"КПП" => 770101001,
"Код по ОКПО" => 71630621,
"Форма собственности (по ОКФС)" => "34 Совместная частная и иностранная собственность",
"Организационно-правовая форма (по ОКОПФ)" => "12247 Публичные акционерные общества",
"Вид экономической деятельности по ОКВЭД 2" => "70.10.1",
"Местонахождение (адрес)" => "105066, г. Москва, ул. Красносельская Нижн., д. 40/12, к. 20, пом. II"
}
}
organizations = Organization.all
@info_about_organisations = organizations.each_with_object({}) do |org, hash|
hash[org.id] = {
"ИНН" => org.inn,
"Полное наименование юридического лица" => org.full_name,
"КПП" => org.kpp,
"Код по ОКПО" => org.okpo,
"Форма собственности (по ОКФС)" => org.okfs,
"Организационно-правовая форма (по ОКОПФ)" => org.okopf,
"Вид экономической деятельности по ОКВЭД 2" => org.okved2,
"Местонахождение (адрес)" => org.address
}
end
end
end
+98
View File
@@ -0,0 +1,98 @@
require 'roo'
class ReportParser
SHEET_NAME = 'Сведения об организации'
CELL_MAP = {
full_name: { row: 6, col: 13 },
inn: { row: 10, col: 13 },
kpp: { row: 11, col: 13 },
okpo: { row: 12, col: 13 },
okfs: { row: 13, col: 13 },
okopf: { row: 14, col: 13 },
okved2: { row: 15, col: 13 },
address: { row: 16, col: 13 }
}.freeze
AUDITOR_MAP = {
name: { row: 19, col: 13 },
inn: { row: 20, col: 13 },
ogrn: { row: 21, col: 13 }
}.freeze
def initialize(yearly_file)
@yearly_file = yearly_file
end
def call
ActiveRecord::Base.transaction do
parse_organization
parse_auditor
extract_year
end
end
private
def spreadsheet
@spreadsheet ||= begin
tempfile = Tempfile.new(['report', '.xlsx'])
tempfile.binmode
@yearly_file.file.download { |chunk| tempfile.write(chunk) }
tempfile.rewind
Roo::Excelx.new(tempfile.path)
end
end
def info_sheet
@info_sheet ||= spreadsheet.sheet(SHEET_NAME)
end
def read_cell(sheet, row, col)
value = sheet.cell(row, col)
value.is_a?(String) ? value.strip.presence : value
end
def parse_organization
org_data = CELL_MAP.each_with_object({}) do |(attr, pos), hash|
hash[attr] = read_cell(info_sheet, pos[:row], pos[:col])
end
organization = @yearly_file.organization
organization.update!(org_data)
organization
end
def parse_auditor
auditor_data = AUDITOR_MAP.each_with_object({}) do |(attr, pos), hash|
hash[attr] = read_cell(info_sheet, pos[:row], pos[:col])
end
return if auditor_data[:name].blank?
auditor_inn = auditor_data[:inn].to_s.strip
auditor = if auditor_inn.present?
Auditor.find_or_initialize_by(inn: auditor_inn)
else
Auditor.find_or_initialize_by(name: auditor_data[:name])
end
auditor.assign_attributes(
name: auditor_data[:name],
inn: auditor_inn.presence,
ogrn: auditor_data[:ogrn].to_s.strip.presence
)
auditor.save!
@yearly_file.update!(auditor: auditor)
auditor
end
def extract_year
balance_sheet = spreadsheet.sheet('Бухгалтерский баланс')
period_text = balance_sheet.cell(4, 1).to_s
year = period_text.match(/(\d{4})/)&.captures&.first&.to_i
@yearly_file.update!(year: year) if year
year
end
end
+16 -1
View File
@@ -15,11 +15,26 @@ class FileProcessorJob
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
# Удали временные файлы
@@ -69,4 +84,4 @@ class FileProcessorJob
end
end
end
end
end