179 lines
6.1 KiB
Ruby
179 lines
6.1 KiB
Ruby
class OrganisationsController < ApplicationController
|
||
before_action :set_organisation, only: [:show, :destroy, :reload]
|
||
|
||
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
|
||
@pagy, organizations = pagy(Organization.order(:created_at))
|
||
|
||
@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
|
||
|
||
|
||
def destroy
|
||
@org.destroy!
|
||
redirect_to '/organisations/index', notice: "Организация #{@org.inn} удалена"
|
||
end
|
||
|
||
def reload
|
||
report = Report.create!(inn: @org.inn, status: 'processing')
|
||
FileProcessorJob.perform_async(@org.inn, report.id)
|
||
redirect_to "/organisations/#{@org.id}", notice: 'Данные обновляются в фоне'
|
||
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 |