Files
finreport-analyzer/app/controllers/organisations_controller.rb
T

168 lines
5.7 KiB
Ruby
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
class OrganisationsController < ApplicationController
before_action :set_organisation, only: [:show]
DOC_TYPES = {
0 => { title: 'Бухгалтерский баланс', form_code: '1.1' },
1 => { title: 'Отчёт о финансовых результатах', form_code: '1.2' },
2 => { title: 'Отчёт об изменении капитала', form_code: '1.3' },
3 => { title: 'Отчёт о движении денежных средств', form_code: '1.4' }
}.freeze
def index
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
def show
@type_doc = params[:type_doc].present? ? params[:type_doc].to_i : 0
statements_by_year_and_form = build_statements_by_year_and_form
years = statements_by_year_and_form.keys.sort.reverse
grouped_rows = clean_data(build_grouped_rows(statements_by_year_and_form, years))
@info_about_organisation = build_organization_payload(years)
selected_doc = DOC_TYPES.fetch(@type_doc, DOC_TYPES[0])
@doc_name = selected_doc[:title]
@current_doc_info1 = grouped_rows[@doc_name]
if !@current_doc_info1.values.first.nil?
@current_doc_info = @info_about_organisation[@doc_name][0..@current_doc_info1.values.first.size + 1]
end
end
private
def set_organisation
@org = Organization.find(params[:id])
end
def build_organization_payload(years)
payload = {
'Сведения об организации' => {
'ИНН' => @org.inn,
'Полное наименование юридического лица' => @org.full_name,
'КПП' => @org.kpp,
'Код по ОКПО' => @org.okpo,
'Форма собственности (по ОКФС)' => @org.okfs,
'Организационно-правовая форма (по ОКОПФ)' => @org.okopf,
'Вид экономической деятельности по ОКВЭД 2' => @org.okved2,
'Местонахождение (адрес)' => @org.address
}
}
DOC_TYPES.each_value do |doc_type|
payload[doc_type[:title]] = ['Наименование показателя', 'Код'] + years.map do |year|
column_header_for(doc_type[:form_code], year)
end
end
payload
end
def build_grouped_rows(statements_by_year_and_form, years)
data = DOC_TYPES.each_with_object({}) do |(_, doc_type), hash|
hash[doc_type[:title]] = {}
end
years.each do |year|
DOC_TYPES.each_value do |doc_type|
statement = statements_by_year_and_form.dig(year, doc_type[:form_code])
rows = statement ? extract_rows(statement, doc_type[:form_code]) : []
rows.each do |row|
line_name = row['line_name'] || row[:line_name]
line_code = row['line_code'] || row[:line_code]
next if line_name.blank? && line_code.blank?
key = [line_name, line_code]
data[doc_type[:title]][key] ||= []
data[doc_type[:title]][key] << (row['value'] || row[:value] || '-')
end
end
end
data
end
def clean_data(data)
data.transform_values do |doc_type_data|
rows = doc_type_data.reject do |_, values|
values.all? { |value| value == "-" || value.nil? || value == ""}
end
next {} if rows.empty?
column_count = rows.values.map(&:size).max
columns_to_keep = (0...column_count).select do |i|
rows.values.any? { |values| values[i] != "-" && !values[i].nil? && values[i] != ""}
end
rows.transform_values do |values|
columns_to_keep.map { |i| values[i]}
end
end
end
def build_statements_by_year_and_form
grouped = Hash.new { |hash, key| hash[key] = {} }
@org.financial_statements.includes(:yearly_file).each do |statement|
year = statement.sheet_number.to_i
next unless year.positive?
next unless unified_statement?(statement)
DOC_TYPES.each_value do |doc_type|
form_code = doc_type[:form_code]
next if extract_rows(statement, form_code).blank?
current = grouped[year][form_code]
grouped[year][form_code] = statement if better_statement?(statement, current)
end
end
grouped
end
def better_statement?(candidate, current)
return true if current.nil?
candidate_source_year = candidate.yearly_file&.year.to_i
current_source_year = current.yearly_file&.year.to_i
return true if candidate_source_year > current_source_year
return false if candidate_source_year < current_source_year
candidate.updated_at > current.updated_at
end
def unified_statement?(statement)
forms = statement.data.is_a?(Hash) ? (statement.data['forms'] || statement.data[:forms]) : nil
forms.is_a?(Hash)
end
def extract_rows(statement, form_code)
forms = statement.data['forms'] || statement.data[:forms] || {}
form_payload = forms[form_code] || forms[form_code.to_sym] || {}
rows = form_payload['rows'] || form_payload[:rows] || []
return rows if rows.is_a?(Array)
[]
end
def column_header_for(form_code, year)
return "На 31 декабря #{year} г." if form_code == '1.1'
"За #{year} г."
end
end