99 lines
2.4 KiB
Ruby
99 lines
2.4 KiB
Ruby
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
|