Class: FinModeling::ComprehensiveIncomeStatementCalculation

Inherits:
CompanyFilingCalculation show all
Includes:
CanChooseSuccessivePeriods
Defined in:
lib/finmodeling/comprehensive_income_statement_calculation.rb

Constant Summary collapse

CI_GOAL =
"comprehensive income"
CI_LABELS =
[ /^comprehensive (income|loss|loss income|income loss)(| net of tax)(| attributable to .*)$/ ]
CI_ANTI_LABELS =
[ /noncontrolling interest/, 
/minority interest/ ]
CI_IDS =
[ /^(|Locator_|loc_)(|us-gaap_)ComprehensiveIncomeNetOfTax[_0-9a-z]+/ ]

Instance Attribute Summary

Attributes inherited from CompanyFilingCalculation

#calculation

Instance Method Summary collapse

Methods inherited from CompanyFilingCalculation

#initialize, #label, #leaf_items, #leaf_items_sum, #periods, #summary

Constructor Details

This class inherits a constructor from FinModeling::CompanyFilingCalculation

Instance Method Details

#comprehensive_income_calculationObject



10
11
12
13
14
15
16
17
# File 'lib/finmodeling/comprehensive_income_statement_calculation.rb', line 10

def comprehensive_income_calculation
  begin
    @ci ||= ComprehensiveIncomeCalculation.new(find_calculation_arc(CI_GOAL, CI_LABELS, CI_ANTI_LABELS, CI_IDS))
  rescue FinModeling::InvalidFilingError => e
    pre_msg = "calculation tree:\n" + self.calculation.sprint_tree
    raise e, pre_msg+e.message, e.backtrace
  end
end

#is_valid?Boolean

Returns:

  • (Boolean)


19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/finmodeling/comprehensive_income_statement_calculation.rb', line 19

def is_valid?
  if !comprehensive_income_calculation.has_net_income_item? && !comprehensive_income_calculation.has_revenue_item?
    puts "comprehensive income statement's comprehensive income calculation lacks net income item"
    puts "comprehensive income statement's comprehensive income calculation lacks sales/revenue item"
    if comprehensive_income_calculation
      puts "summary:"
      comprehensive_income_calculation.summary(:period => periods.last).print
    end
    puts "calculation tree:\n" + self.calculation.sprint_tree(indent_count=0, simplified=true)
  end
  return (comprehensive_income_calculation.has_revenue_item? || comprehensive_income_calculation.has_net_income_item?)
end

#latest_quarterly_reformulated(dummy_cur_ci_calc, prev_stmt, prev_ci_calc) ⇒ Object



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/finmodeling/comprehensive_income_statement_calculation.rb', line 40

def latest_quarterly_reformulated(dummy_cur_ci_calc, prev_stmt, prev_ci_calc)
  if comprehensive_income_calculation.periods.quarterly.any?
    period = comprehensive_income_calculation.periods.quarterly.last
    lqr = reformulated(period, comprehensive_income_calculation)

    if (lqr.operating_revenues.total.abs > 1.0) && # FIXME: make an is_valid here?
       (lqr.cost_of_revenues  .total.abs > 1.0)    # FIXME: make an is_valid here?
      return lqr
    end
  end

  return nil if !prev_stmt

  prev_calc = prev_stmt.respond_to?(:net_income_calculation) ? prev_stmt.net_income_calculation : prev_stmt.comprehensive_income_calculation

  cur_period, prev_period = choose_successive_periods(comprehensive_income_calculation, prev_calc)
  if cur_period && prev_period
    new_re_is = reformulated(cur_period, comprehensive_income_calculation) - prev_stmt.reformulated(prev_period, prev_ci_calc)
    # the above subtraction doesn't know what period you want. So let's patch the result to have
    # a quarterly period with the right end-points
    new_re_is.period = Xbrlware::Context::Period.new({"start_date"=>prev_period.value["end_date"],
                                                      "end_date"  =>cur_period.value["end_date"]})
    return new_re_is
  end

  return nil
end

#reformulated(period, dummy_comprehensive_income_calculation) ⇒ Object

2nd param is just to keep signature consistent w/ IncomeStatement::reformulated



32
33
34
35
36
37
38
# File 'lib/finmodeling/comprehensive_income_statement_calculation.rb', line 32

def reformulated(period, dummy_comprehensive_income_calculation) # 2nd param is just to keep signature consistent w/ IncomeStatement::reformulated
  # The way ReformulatedIncomeStatement.new() is implemented, it'll just ignore rows with types it 
  # doesn't know about (like OCI). So this should extract just the NI-related rows.
  return ReformulatedIncomeStatement.new(period,
                                         comprehensive_income_calculation.summary(:period=>period), # NI
                                         comprehensive_income_calculation.summary(:period=>period)) # CI
end

#write_constructor(file, item_name) ⇒ Object



68
69
70
71
72
# File 'lib/finmodeling/comprehensive_income_statement_calculation.rb', line 68

def write_constructor(file, item_name)
  item_calc_name = item_name + "_calc"
  @calculation.write_constructor(file, item_calc_name)
  file.puts "#{item_name} = FinModeling::ComprehensiveIncomeStatementCalculation.new(#{item_calc_name})"
end