Контроллер настроен на парсер, готово к PR
This commit is contained in:
@@ -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
|
||||
Reference in New Issue
Block a user